From 251d9aaa81bc6cbf0d1b00e1a0becc40f608e8d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 05:51:13 +0000 Subject: [PATCH 1/2] Bump friendsofphp/php-cs-fixer from 3.38.2 to 3.56.1 Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.38.2 to 3.56.1. - [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases) - [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md) - [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.38.2...v3.56.1) --- updated-dependencies: - dependency-name: friendsofphp/php-cs-fixer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- composer.json | 2 +- composer.lock | 56 +++++++++++++++++++++++++-------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index 229e0223..b9d96387 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "require": { "php": ">=7.4", "rector/rector": "1.0.5", - "friendsofphp/php-cs-fixer": "3.38.2", + "friendsofphp/php-cs-fixer": "3.56.1", "redaxo/php-cs-fixer-config": "^1.0" }, "config": { diff --git a/composer.lock b/composer.lock index c88e43f4..e02ecca0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "95ff7e8f234a2bf2a45b6eda334f9b72", + "content-hash": "b93c814ff9294c8fb33e24f6e387c2e7", "packages": [ { "name": "composer/pcre", @@ -226,50 +226,50 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.38.2", + "version": "v3.56.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "d872cdd543797ade030aaa307c0a4954a712e081" + "reference": "69c6168ae8bc96dc656c7f6c7271120a68ae5903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d872cdd543797ade030aaa307c0a4954a712e081", - "reference": "d872cdd543797ade030aaa307c0a4954a712e081", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/69c6168ae8bc96dc656c7f6c7271120a68ae5903", + "reference": "69c6168ae8bc96dc656c7f6c7271120a68ae5903", "shasum": "" }, "require": { - "composer/semver": "^3.3", + "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0 || ^5.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.27", - "symfony/polyfill-php80": "^1.27", - "symfony/polyfill-php81": "^1.27", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { "facile-it/paraunit": "^1.3 || ^2.0", + "infection/infection": "^0.27.11", "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.0", + "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.5.3", + "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.16", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "symfony/phpunit-bridge": "^6.2.3", - "symfony/yaml": "^5.4 || ^6.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -307,7 +307,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.38.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.56.1" }, "funding": [ { @@ -315,7 +315,7 @@ "type": "github" } ], - "time": "2023-11-14T00:19:22+00:00" + "time": "2024-05-10T11:31:15+00:00" }, { "name": "phpstan/phpstan", From 9dac8d2f676b5777dd95fa8c22a20b9bcb88c655 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 11 May 2024 07:51:50 +0200 Subject: [PATCH 2/2] update vendor --- vendor/composer/autoload_classmap.php | 20 +- vendor/composer/autoload_static.php | 20 +- vendor/composer/installed.json | 56 +- vendor/composer/installed.php | 10 +- vendor/friendsofphp/php-cs-fixer/CHANGELOG.md | 502 +++++++++++- .../friendsofphp/php-cs-fixer/CONTRIBUTING.md | 38 +- vendor/friendsofphp/php-cs-fixer/README.md | 29 +- .../friendsofphp/php-cs-fixer/UPGRADE-v3.md | 169 ++-- .../php-cs-fixer/ci-integration.sh | 2 +- .../friendsofphp/php-cs-fixer/composer.json | 65 +- vendor/friendsofphp/php-cs-fixer/logo.md | 2 +- vendor/friendsofphp/php-cs-fixer/php-cs-fixer | 4 +- .../src/AbstractFunctionReferenceFixer.php | 2 +- .../src/AbstractNoUselessElseFixer.php | 2 +- .../AbstractPhpdocToTypeDeclarationFixer.php | 22 +- .../src/AbstractPhpdocTypesFixer.php | 41 +- .../php-cs-fixer/src/AbstractProxyFixer.php | 2 +- .../php-cs-fixer/src/Cache/Cache.php | 2 +- .../src/Cache/CacheManagerInterface.php | 2 + .../src/Cache/FileCacheManager.php | 11 +- .../src/Cache/NullCacheManager.php | 3 + .../friendsofphp/php-cs-fixer/src/Config.php | 17 +- .../php-cs-fixer/src/ConfigInterface.php | 4 +- .../php-cs-fixer/src/Console/Application.php | 45 +- .../src/Console/Command/CheckCommand.php | 3 + .../src/Console/Command/DescribeCommand.php | 112 ++- .../Console/Command/DocumentationCommand.php | 33 +- .../src/Console/Command/FixCommand.php | 11 +- .../src/Console/Command/HelpCommand.php | 1 + .../src/Console/Command/ListFilesCommand.php | 1 + .../src/Console/Command/ListSetsCommand.php | 1 + .../src/Console/Command/SelfUpdateCommand.php | 12 +- .../src/Console/ConfigurationResolver.php | 37 +- .../src/Console/Output/ErrorOutput.php | 5 +- .../Console/Output/Progress/DotsOutput.php | 4 +- .../Output/Progress/PercentageBarOutput.php | 76 ++ .../Output/Progress/ProgressOutputFactory.php | 18 +- .../Output/Progress/ProgressOutputType.php | 16 +- .../Report/FixReport/CheckstyleReporter.php | 4 + .../Report/FixReport/GitlabReporter.php | 36 +- .../Console/Report/FixReport/JsonReporter.php | 6 +- .../Report/FixReport/JunitReporter.php | 10 +- .../Report/FixReport/ReporterFactory.php | 2 +- .../Console/Report/FixReport/TextReporter.php | 4 +- .../Console/Report/FixReport/XmlReporter.php | 15 +- .../Report/ListSetsReport/JsonReporter.php | 2 +- .../Report/ListSetsReport/ReporterFactory.php | 2 +- .../Report/ListSetsReport/TextReporter.php | 2 +- .../src/Console/SelfUpdate/GithubClient.php | 23 +- .../SelfUpdate/GithubClientInterface.php | 7 +- .../Console/SelfUpdate/NewVersionChecker.php | 11 +- .../src/Console/WarningsDetector.php | 10 +- .../php-cs-fixer/src/DocBlock/Annotation.php | 30 +- .../php-cs-fixer/src/DocBlock/Line.php | 4 +- .../src/DocBlock/TagComparator.php | 4 +- .../src/DocBlock/TypeExpression.php | 120 ++- .../src/Doctrine/Annotation/DocLexer.php | 2 +- .../src/Doctrine/Annotation/Token.php | 2 +- .../src/Doctrine/Annotation/Tokens.php | 27 +- .../Documentation/DocumentationLocator.php | 7 +- .../Documentation/FixerDocumentGenerator.php | 87 +- .../Documentation/ListDocumentGenerator.php | 170 ---- .../RuleSetDocumentationGenerator.php | 67 +- .../php-cs-fixer/src/Error/ErrorsManager.php | 8 +- .../src/ExecutorWithoutErrorHandler.php | 58 ++ .../ExecutorWithoutErrorHandlerException.php | 22 + .../php-cs-fixer/src/FileRemoval.php | 4 +- .../src/Fixer/AbstractPhpUnitFixer.php | 70 +- .../Fixer/Alias/BacktickToShellExecFixer.php | 7 +- .../src/Fixer/Alias/EregToPregFixer.php | 2 +- .../src/Fixer/Alias/MbStrFunctionsFixer.php | 10 + .../src/Fixer/Alias/NoAliasFunctionsFixer.php | 2 +- .../src/Fixer/Alias/NoMixedEchoPrintFixer.php | 24 +- .../Fixer/Alias/PowToExponentiationFixer.php | 4 +- .../src/Fixer/Alias/SetTypeToCastFixer.php | 2 +- .../Fixer/ArrayNotation/ArraySyntaxFixer.php | 21 +- .../WhitespaceAfterCommaInArrayFixer.php | 2 +- .../YieldFromArrayToYieldsFixer.php | 2 +- .../OrderedAttributesFixer.php | 310 +++++++ .../src/Fixer/Basic/BracesFixer.php | 22 +- .../src/Fixer/Basic/BracesPositionFixer.php | 4 +- .../NoTrailingCommaInSinglelineFixer.php | 2 +- .../Basic/NonPrintableCharacterFixer.php | 8 +- .../Basic/NumericLiteralSeparatorFixer.php | 217 +++++ .../src/Fixer/Basic/PsrAutoloadingFixer.php | 2 +- .../Casing/ClassReferenceNameCasingFixer.php | 4 + .../src/Fixer/Casing/ConstantCaseFixer.php | 6 +- .../Fixer/Casing/LowercaseKeywordsFixer.php | 2 +- .../Casing/LowercaseStaticReferenceFixer.php | 2 +- .../Fixer/Casing/MagicConstantCasingFixer.php | 2 +- .../Fixer/Casing/MagicMethodCasingFixer.php | 2 +- .../NativeTypeDeclarationCasingFixer.php | 10 +- .../ClassAttributesSeparationFixer.php | 45 +- .../ClassNotation/ClassDefinitionFixer.php | 74 +- .../ClassNotation/FinalInternalClassFixer.php | 4 +- .../ClassNotation/NoPhp4ConstructorFixer.php | 2 +- .../OrderedClassElementsFixer.php | 126 ++- .../ClassNotation/OrderedInterfacesFixer.php | 22 +- .../ClassNotation/OrderedTraitsFixer.php | 4 +- .../Fixer/ClassNotation/OrderedTypesFixer.php | 22 +- .../Fixer/ClassNotation/SelfAccessorFixer.php | 2 +- .../SingleClassElementPerStatementFixer.php | 2 +- .../SingleTraitInsertPerStatementFixer.php | 4 +- .../Fixer/Comment/CommentToPhpdocFixer.php | 16 +- .../src/Fixer/Comment/HeaderCommentFixer.php | 8 +- .../MultilineCommentOpeningClosingFixer.php | 4 +- .../src/Fixer/Comment/NoEmptyCommentFixer.php | 20 +- .../Comment/SingleLineCommentStyleFixer.php | 4 +- .../EmptyLoopConditionFixer.php | 2 +- .../ControlStructure/NoBreakCommentFixer.php | 2 +- .../NoUnneededBracesFixer.php | 12 +- .../NoUnneededControlParenthesesFixer.php | 4 +- .../SimplifiedIfReturnFixer.php | 4 +- .../SwitchContinueToBreakFixer.php | 2 +- .../TrailingCommaInMultilineFixer.php | 7 +- .../Fixer/ControlStructure/YodaStyleFixer.php | 5 +- .../src/Fixer/DeprecatedFixerInterface.php | 2 +- .../DoctrineAnnotationIndentationFixer.php | 4 +- .../src/Fixer/ExperimentalFixerInterface.php | 20 + .../CombineNestedDirnameFixer.php | 6 +- .../DateTimeCreateFromFormatCallFixer.php | 2 +- .../FunctionNotation/FopenFlagOrderFixer.php | 4 +- .../FunctionNotation/ImplodeCallFixer.php | 4 +- .../LambdaNotUsedImportFixer.php | 13 + .../MethodArgumentSpaceFixer.php | 4 +- .../NativeFunctionInvocationFixer.php | 11 +- .../NoSpacesAfterFunctionNameFixer.php | 16 +- ...ypeDeclarationForDefaultNullValueFixer.php | 3 +- .../PhpdocToParamTypeFixer.php | 26 +- .../PhpdocToPropertyTypeFixer.php | 32 +- .../PhpdocToReturnTypeFixer.php | 35 +- .../RegularCallableCallFixer.php | 2 +- .../FunctionNotation/VoidReturnFixer.php | 2 +- .../Import/FullyQualifiedStrictTypesFixer.php | 766 ++++++++++++++++-- .../Import/GlobalNamespaceImportFixer.php | 103 +-- .../src/Fixer/Import/GroupImportFixer.php | 14 +- .../src/Fixer/Import/NoUnusedImportsFixer.php | 207 ++++- .../src/Fixer/Import/OrderedImportsFixer.php | 62 +- .../Import/SingleImportPerStatementFixer.php | 7 +- .../LanguageConstruct/ClassKeywordFixer.php | 100 +++ .../ClassKeywordRemoveFixer.php | 4 +- .../CombineConsecutiveIssetsFixer.php | 8 +- .../CombineConsecutiveUnsetsFixer.php | 4 +- .../DeclareEqualNormalizeFixer.php | 19 +- .../FunctionToConstantFixer.php | 34 +- .../NoUnsetOnPropertyFixer.php | 4 +- .../SingleSpaceAroundConstructFixer.php | 43 +- .../Fixer/ListNotation/ListSyntaxFixer.php | 2 +- .../BlankLinesBeforeNamespaceFixer.php | 4 +- .../NamespaceNotation/CleanNamespaceFixer.php | 2 +- .../Fixer/Naming/NoHomoglyphNamesFixer.php | 2 +- .../Operator/BinaryOperatorSpacesFixer.php | 4 +- .../src/Fixer/Operator/ConcatSpaceFixer.php | 23 +- .../Operator/LongToShorthandOperatorFixer.php | 2 +- .../Operator/NewWithParenthesesFixer.php | 4 +- .../NoSpaceAroundDoubleColonFixer.php | 10 + .../Operator/NoUselessConcatOperatorFixer.php | 115 +-- .../Fixer/Operator/OperatorLinebreakFixer.php | 47 +- .../Operator/TernaryOperatorSpacesFixer.php | 31 +- .../Operator/TernaryToElvisOperatorFixer.php | 11 +- .../Operator/UnaryOperatorSpacesFixer.php | 39 +- .../PhpTag/BlankLineAfterOpeningTagFixer.php | 25 +- .../src/Fixer/PhpTag/EchoTagSyntaxFixer.php | 2 +- .../src/Fixer/PhpTag/FullOpeningTagFixer.php | 2 +- .../PhpTag/LinebreakAfterOpeningTagFixer.php | 13 +- .../src/Fixer/PhpTag/NoClosingTagFixer.php | 8 +- .../Fixer/PhpUnit/PhpUnitAttributesFixer.php | 516 ++++++++++++ .../Fixer/PhpUnit/PhpUnitConstructFixer.php | 39 +- .../PhpUnit/PhpUnitDataProviderNameFixer.php | 22 +- .../PhpUnitDataProviderStaticFixer.php | 4 +- .../PhpUnit/PhpUnitDedicateAssertFixer.php | 4 +- .../PhpUnit/PhpUnitFqcnAnnotationFixer.php | 2 +- .../PhpUnit/PhpUnitInternalClassFixer.php | 5 +- .../PhpUnit/PhpUnitMethodCasingFixer.php | 4 +- .../PhpUnitMockShortWillReturnFixer.php | 4 - .../Fixer/PhpUnit/PhpUnitNamespacedFixer.php | 2 +- .../Fixer/PhpUnit/PhpUnitSizeClassFixer.php | 5 +- .../src/Fixer/PhpUnit/PhpUnitStrictFixer.php | 2 +- .../PhpUnit/PhpUnitTestAnnotationFixer.php | 23 +- .../PhpUnitTestCaseStaticMethodCallsFixer.php | 39 +- .../PhpUnitTestClassRequiresCoversFixer.php | 8 +- .../Phpdoc/AlignMultilineCommentFixer.php | 4 +- .../Phpdoc/GeneralPhpdocTagRenameFixer.php | 6 +- .../src/Fixer/Phpdoc/NoEmptyPhpdocFixer.php | 28 +- .../Phpdoc/NoSuperfluousPhpdocTagsFixer.php | 128 ++- .../PhpdocAddMissingParamAnnotationFixer.php | 2 +- .../src/Fixer/Phpdoc/PhpdocAlignFixer.php | 104 ++- .../PhpdocAnnotationWithoutDotFixer.php | 2 +- .../src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php | 92 +++ .../src/Fixer/Phpdoc/PhpdocIndentFixer.php | 2 +- .../src/Fixer/Phpdoc/PhpdocListTypeFixer.php | 70 ++ .../Phpdoc/PhpdocNoUselessInheritdocFixer.php | 2 +- .../Fixer/Phpdoc/PhpdocOrderByValueFixer.php | 6 +- .../src/Fixer/Phpdoc/PhpdocOrderFixer.php | 17 +- .../Fixer/Phpdoc/PhpdocParamOrderFixer.php | 29 +- .../Phpdoc/PhpdocReturnSelfReferenceFixer.php | 2 +- .../src/Fixer/Phpdoc/PhpdocScalarFixer.php | 12 +- .../Fixer/Phpdoc/PhpdocSeparationFixer.php | 12 +- .../src/Fixer/Phpdoc/PhpdocTagTypeFixer.php | 4 +- .../src/Fixer/Phpdoc/PhpdocToCommentFixer.php | 35 +- ...rimConsecutiveBlankLineSeparationFixer.php | 7 +- .../src/Fixer/Phpdoc/PhpdocTrimFixer.php | 2 +- .../src/Fixer/Phpdoc/PhpdocTypesFixer.php | 43 +- .../Fixer/Phpdoc/PhpdocTypesOrderFixer.php | 10 +- .../Phpdoc/PhpdocVarWithoutNameFixer.php | 2 +- .../SimplifiedNullReturnFixer.php | 3 +- .../Fixer/Strict/DeclareStrictTypesFixer.php | 42 +- .../src/Fixer/Strict/StrictParamFixer.php | 5 +- .../EscapeImplicitBackslashesFixer.php | 96 +-- .../ExplicitStringVariableFixer.php | 5 +- .../HeredocClosingMarkerFixer.php | 188 +++++ .../StringNotation/HeredocToNowdocFixer.php | 6 +- .../MultilineStringToHeredocFixer.php | 166 ++++ .../SimpleToComplexStringVariableFixer.php | 4 +- .../Fixer/StringNotation/SingleQuoteFixer.php | 6 +- .../StringImplicitBackslashesFixer.php | 177 ++++ .../BlankLineBetweenImportGroupsFixer.php | 2 +- .../Whitespace/HeredocIndentationFixer.php | 12 +- .../MethodChainingIndentationFixer.php | 10 + .../Whitespace/NoExtraBlankLinesFixer.php | 62 +- .../Whitespace/NoTrailingWhitespaceFixer.php | 2 +- .../NoWhitespaceInBlankLineFixer.php | 2 +- .../SpacesInsideParenthesesFixer.php | 12 +- .../Whitespace/StatementIndentationFixer.php | 264 ++++-- .../FixerConfiguration/FixerOptionSorter.php | 2 +- .../php-cs-fixer/src/FixerFactory.php | 13 +- .../Indicator/PhpUnitTestCaseIndicator.php | 2 +- .../php-cs-fixer/src/Linter/ProcessLinter.php | 4 +- vendor/friendsofphp/php-cs-fixer/src/Preg.php | 140 ++-- .../DeprecatedRuleSetDescriptionInterface.php | 28 + .../php-cs-fixer/src/RuleSet/RuleSet.php | 22 +- .../src/RuleSet/RuleSetInterface.php | 2 +- .../php-cs-fixer/src/RuleSet/RuleSets.php | 4 +- .../src/RuleSet/Sets/PERCS1x0RiskySet.php | 9 +- .../src/RuleSet/Sets/PERCS1x0Set.php | 9 +- .../src/RuleSet/Sets/PERCS2x0Set.php | 15 +- .../src/RuleSet/Sets/PERRiskySet.php | 14 +- .../php-cs-fixer/src/RuleSet/Sets/PERSet.php | 14 +- .../src/RuleSet/Sets/PHP83MigrationSet.php | 30 + .../src/RuleSet/Sets/PHP84MigrationSet.php | 31 + .../src/RuleSet/Sets/PSR12Set.php | 4 +- .../src/RuleSet/Sets/PhpCsFixerRiskySet.php | 2 +- .../src/RuleSet/Sets/PhpCsFixerSet.php | 9 +- .../src/RuleSet/Sets/SymfonyRiskySet.php | 1 - .../src/RuleSet/Sets/SymfonySet.php | 21 +- .../src/Runner/FileLintingIterator.php | 2 +- .../php-cs-fixer/src/Runner/Runner.php | 4 +- .../php-cs-fixer/src/StdinFileInfo.php | 4 +- .../Analyzer/Analysis/AttributeAnalysis.php | 73 ++ .../Analysis/DataProviderAnalysis.php | 16 +- .../Analysis/NamespaceUseAnalysis.php | 58 +- .../Analyzer/Analysis/TypeAnalysis.php | 5 +- .../Tokenizer/Analyzer/AttributeAnalyzer.php | 109 +++ .../src/Tokenizer/Analyzer/BlocksAnalyzer.php | 10 +- .../Tokenizer/Analyzer/CommentsAnalyzer.php | 56 +- .../Analyzer/DataProviderAnalyzer.php | 9 +- .../Tokenizer/Analyzer/FunctionsAnalyzer.php | 8 +- .../Analyzer/NamespaceUsesAnalyzer.php | 160 +++- .../Tokenizer/Analyzer/NamespacesAnalyzer.php | 11 +- .../src/Tokenizer/Analyzer/SwitchAnalyzer.php | 69 ++ .../php-cs-fixer/src/Tokenizer/CT.php | 80 +- .../php-cs-fixer/src/Tokenizer/CodeHasher.php | 2 + .../Tokenizer/Processor/ImportProcessor.php | 101 +++ .../php-cs-fixer/src/Tokenizer/Token.php | 21 +- .../php-cs-fixer/src/Tokenizer/Tokens.php | 316 +++++--- .../src/Tokenizer/TokensAnalyzer.php | 12 +- .../Transformer/NameQualifiedTransformer.php | 30 +- .../src/Tokenizer/Transformers.php | 2 +- .../php-cs-fixer/src/ToolInfo.php | 9 + .../php-cs-fixer/src/ToolInfoInterface.php | 2 + .../friendsofphp/php-cs-fixer/src/Utils.php | 33 +- .../php-cs-fixer/src/WordMatcher.php | 4 +- 272 files changed, 6931 insertions(+), 2204 deletions(-) create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/PercentageBarOutput.php delete mode 100644 vendor/friendsofphp/php-cs-fixer/src/Documentation/ListDocumentGenerator.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandler.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandlerException.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NumericLiteralSeparatorFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/ExperimentalFixerInterface.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocListTypeFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocClosingMarkerFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/MultilineStringToHeredocFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringImplicitBackslashesFixer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/RuleSet/DeprecatedRuleSetDescriptionInterface.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AttributeAnalysis.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/SwitchAnalyzer.php create mode 100644 vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Processor/ImportProcessor.php diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index c795f005..13932954 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -79,6 +79,7 @@ 'PhpCsFixer\\Console\\Output\\OutputContext' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/OutputContext.php', 'PhpCsFixer\\Console\\Output\\Progress\\DotsOutput' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/DotsOutput.php', 'PhpCsFixer\\Console\\Output\\Progress\\NullOutput' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/NullOutput.php', + 'PhpCsFixer\\Console\\Output\\Progress\\PercentageBarOutput' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/PercentageBarOutput.php', 'PhpCsFixer\\Console\\Output\\Progress\\ProgressOutputFactory' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputFactory.php', 'PhpCsFixer\\Console\\Output\\Progress\\ProgressOutputInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputInterface.php', 'PhpCsFixer\\Console\\Output\\Progress\\ProgressOutputType' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputType.php', @@ -118,11 +119,12 @@ 'PhpCsFixer\\Doctrine\\Annotation\\Tokens' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Tokens.php', 'PhpCsFixer\\Documentation\\DocumentationLocator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Documentation/DocumentationLocator.php', 'PhpCsFixer\\Documentation\\FixerDocumentGenerator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Documentation/FixerDocumentGenerator.php', - 'PhpCsFixer\\Documentation\\ListDocumentGenerator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Documentation/ListDocumentGenerator.php', 'PhpCsFixer\\Documentation\\RstUtils' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Documentation/RstUtils.php', 'PhpCsFixer\\Documentation\\RuleSetDocumentationGenerator' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Documentation/RuleSetDocumentationGenerator.php', 'PhpCsFixer\\Error\\Error' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Error/Error.php', 'PhpCsFixer\\Error\\ErrorsManager' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Error/ErrorsManager.php', + 'PhpCsFixer\\ExecutorWithoutErrorHandler' => $vendorDir . '/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandler.php', + 'PhpCsFixer\\ExecutorWithoutErrorHandlerException' => $vendorDir . '/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandlerException.php', 'PhpCsFixer\\FileReader' => $vendorDir . '/friendsofphp/php-cs-fixer/src/FileReader.php', 'PhpCsFixer\\FileRemoval' => $vendorDir . '/friendsofphp/php-cs-fixer/src/FileRemoval.php', 'PhpCsFixer\\Finder' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Finder.php', @@ -175,6 +177,7 @@ 'PhpCsFixer\\Fixer\\ArrayNotation\\WhitespaceAfterCommaInArrayFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php', 'PhpCsFixer\\Fixer\\ArrayNotation\\YieldFromArrayToYieldsFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php', 'PhpCsFixer\\Fixer\\AttributeNotation\\AttributeEmptyParenthesesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/AttributeEmptyParenthesesFixer.php', + 'PhpCsFixer\\Fixer\\AttributeNotation\\OrderedAttributesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php', 'PhpCsFixer\\Fixer\\Basic\\BracesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php', 'PhpCsFixer\\Fixer\\Basic\\BracesPositionFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php', 'PhpCsFixer\\Fixer\\Basic\\CurlyBracesPositionFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/CurlyBracesPositionFixer.php', @@ -182,6 +185,7 @@ 'PhpCsFixer\\Fixer\\Basic\\NoMultipleStatementsPerLineFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoMultipleStatementsPerLineFixer.php', 'PhpCsFixer\\Fixer\\Basic\\NoTrailingCommaInSinglelineFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoTrailingCommaInSinglelineFixer.php', 'PhpCsFixer\\Fixer\\Basic\\NonPrintableCharacterFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NonPrintableCharacterFixer.php', + 'PhpCsFixer\\Fixer\\Basic\\NumericLiteralSeparatorFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NumericLiteralSeparatorFixer.php', 'PhpCsFixer\\Fixer\\Basic\\OctalNotationFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/OctalNotationFixer.php', 'PhpCsFixer\\Fixer\\Basic\\PsrAutoloadingFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/PsrAutoloadingFixer.php', 'PhpCsFixer\\Fixer\\Basic\\SingleLineEmptyBodyFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/SingleLineEmptyBodyFixer.php', @@ -256,6 +260,7 @@ 'PhpCsFixer\\Fixer\\DoctrineAnnotation\\DoctrineAnnotationBracesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationBracesFixer.php', 'PhpCsFixer\\Fixer\\DoctrineAnnotation\\DoctrineAnnotationIndentationFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationIndentationFixer.php', 'PhpCsFixer\\Fixer\\DoctrineAnnotation\\DoctrineAnnotationSpacesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationSpacesFixer.php', + 'PhpCsFixer\\Fixer\\ExperimentalFixerInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/ExperimentalFixerInterface.php', 'PhpCsFixer\\Fixer\\FixerInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/FixerInterface.php', 'PhpCsFixer\\Fixer\\FunctionNotation\\CombineNestedDirnameFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/CombineNestedDirnameFixer.php', 'PhpCsFixer\\Fixer\\FunctionNotation\\DateTimeCreateFromFormatCallFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php', @@ -291,6 +296,7 @@ 'PhpCsFixer\\Fixer\\Import\\SingleImportPerStatementFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleImportPerStatementFixer.php', 'PhpCsFixer\\Fixer\\Import\\SingleLineAfterImportsFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleLineAfterImportsFixer.php', 'PhpCsFixer\\Fixer\\Indentation' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Indentation.php', + 'PhpCsFixer\\Fixer\\LanguageConstruct\\ClassKeywordFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordFixer.php', 'PhpCsFixer\\Fixer\\LanguageConstruct\\ClassKeywordRemoveFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordRemoveFixer.php', 'PhpCsFixer\\Fixer\\LanguageConstruct\\CombineConsecutiveIssetsFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php', 'PhpCsFixer\\Fixer\\LanguageConstruct\\CombineConsecutiveUnsetsFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveUnsetsFixer.php', @@ -340,6 +346,7 @@ 'PhpCsFixer\\Fixer\\PhpTag\\FullOpeningTagFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/FullOpeningTagFixer.php', 'PhpCsFixer\\Fixer\\PhpTag\\LinebreakAfterOpeningTagFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/LinebreakAfterOpeningTagFixer.php', 'PhpCsFixer\\Fixer\\PhpTag\\NoClosingTagFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/NoClosingTagFixer.php', + 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitAttributesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php', 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitConstructFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php', 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderNameFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php', 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderReturnTypeFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderReturnTypeFixer.php', @@ -370,9 +377,11 @@ 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocAddMissingParamAnnotationFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocAlignFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAlignFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocAnnotationWithoutDotFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php', + 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocArrayTypeFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocIndentFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocIndentFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocInlineTagNormalizerFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocInlineTagNormalizerFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocLineSpanFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocLineSpanFixer.php', + 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocListTypeFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocListTypeFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocNoAccessFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoAccessFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocNoAliasTagFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoAliasTagFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocNoEmptyReturnFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoEmptyReturnFixer.php', @@ -408,11 +417,14 @@ 'PhpCsFixer\\Fixer\\Strict\\StrictParamFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Strict/StrictParamFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\EscapeImplicitBackslashesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/EscapeImplicitBackslashesFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\ExplicitStringVariableFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/ExplicitStringVariableFixer.php', + 'PhpCsFixer\\Fixer\\StringNotation\\HeredocClosingMarkerFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocClosingMarkerFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\HeredocToNowdocFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocToNowdocFixer.php', + 'PhpCsFixer\\Fixer\\StringNotation\\MultilineStringToHeredocFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/MultilineStringToHeredocFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\NoBinaryStringFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/NoBinaryStringFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\NoTrailingWhitespaceInStringFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/NoTrailingWhitespaceInStringFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\SimpleToComplexStringVariableFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SimpleToComplexStringVariableFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\SingleQuoteFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SingleQuoteFixer.php', + 'PhpCsFixer\\Fixer\\StringNotation\\StringImplicitBackslashesFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringImplicitBackslashesFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\StringLengthToEmptyFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringLengthToEmptyFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\StringLineEndingFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringLineEndingFixer.php', 'PhpCsFixer\\Fixer\\Whitespace\\ArrayIndentationFixer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/ArrayIndentationFixer.php', @@ -453,6 +465,7 @@ 'PhpCsFixer\\PregException' => $vendorDir . '/friendsofphp/php-cs-fixer/src/PregException.php', 'PhpCsFixer\\RuleSet\\AbstractMigrationSetDescription' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/AbstractMigrationSetDescription.php', 'PhpCsFixer\\RuleSet\\AbstractRuleSetDescription' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/AbstractRuleSetDescription.php', + 'PhpCsFixer\\RuleSet\\DeprecatedRuleSetDescriptionInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/DeprecatedRuleSetDescriptionInterface.php', 'PhpCsFixer\\RuleSet\\RuleSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php', 'PhpCsFixer\\RuleSet\\RuleSetDescriptionInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetDescriptionInterface.php', 'PhpCsFixer\\RuleSet\\RuleSetInterface' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetInterface.php', @@ -479,6 +492,8 @@ 'PhpCsFixer\\RuleSet\\Sets\\PHP80MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP80MigrationSet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHP81MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP81MigrationSet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHP82MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationSet.php', + 'PhpCsFixer\\RuleSet\\Sets\\PHP83MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php', + 'PhpCsFixer\\RuleSet\\Sets\\PHP84MigrationSet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHPUnit100MigrationRiskySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHPUnit100MigrationRiskySet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHPUnit30MigrationRiskySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHPUnit30MigrationRiskySet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHPUnit32MigrationRiskySet' => $vendorDir . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHPUnit32MigrationRiskySet.php', @@ -512,6 +527,7 @@ 'PhpCsFixer\\Tokenizer\\Analyzer\\AlternativeSyntaxAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/AlternativeSyntaxAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\AbstractControlCaseStructuresAnalysis' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AbstractControlCaseStructuresAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\ArgumentAnalysis' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/ArgumentAnalysis.php', + 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\AttributeAnalysis' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AttributeAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\CaseAnalysis' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/CaseAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\DataProviderAnalysis' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DataProviderAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\DefaultAnalysis' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DefaultAnalysis.php', @@ -535,9 +551,11 @@ 'PhpCsFixer\\Tokenizer\\Analyzer\\NamespacesAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespacesAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\RangeAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/RangeAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\ReferenceAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/ReferenceAnalyzer.php', + 'PhpCsFixer\\Tokenizer\\Analyzer\\SwitchAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/SwitchAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\WhitespacesAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/WhitespacesAnalyzer.php', 'PhpCsFixer\\Tokenizer\\CT' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/CT.php', 'PhpCsFixer\\Tokenizer\\CodeHasher' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/CodeHasher.php', + 'PhpCsFixer\\Tokenizer\\Processor\\ImportProcessor' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Processor/ImportProcessor.php', 'PhpCsFixer\\Tokenizer\\Token' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Token.php', 'PhpCsFixer\\Tokenizer\\Tokens' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/Tokens.php', 'PhpCsFixer\\Tokenizer\\TokensAnalyzer' => $vendorDir . '/friendsofphp/php-cs-fixer/src/Tokenizer/TokensAnalyzer.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 15008555..6e35661a 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -237,6 +237,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Console\\Output\\OutputContext' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/OutputContext.php', 'PhpCsFixer\\Console\\Output\\Progress\\DotsOutput' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/DotsOutput.php', 'PhpCsFixer\\Console\\Output\\Progress\\NullOutput' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/NullOutput.php', + 'PhpCsFixer\\Console\\Output\\Progress\\PercentageBarOutput' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/PercentageBarOutput.php', 'PhpCsFixer\\Console\\Output\\Progress\\ProgressOutputFactory' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputFactory.php', 'PhpCsFixer\\Console\\Output\\Progress\\ProgressOutputInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputInterface.php', 'PhpCsFixer\\Console\\Output\\Progress\\ProgressOutputType' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputType.php', @@ -276,11 +277,12 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Doctrine\\Annotation\\Tokens' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Tokens.php', 'PhpCsFixer\\Documentation\\DocumentationLocator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Documentation/DocumentationLocator.php', 'PhpCsFixer\\Documentation\\FixerDocumentGenerator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Documentation/FixerDocumentGenerator.php', - 'PhpCsFixer\\Documentation\\ListDocumentGenerator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Documentation/ListDocumentGenerator.php', 'PhpCsFixer\\Documentation\\RstUtils' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Documentation/RstUtils.php', 'PhpCsFixer\\Documentation\\RuleSetDocumentationGenerator' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Documentation/RuleSetDocumentationGenerator.php', 'PhpCsFixer\\Error\\Error' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Error/Error.php', 'PhpCsFixer\\Error\\ErrorsManager' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Error/ErrorsManager.php', + 'PhpCsFixer\\ExecutorWithoutErrorHandler' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandler.php', + 'PhpCsFixer\\ExecutorWithoutErrorHandlerException' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandlerException.php', 'PhpCsFixer\\FileReader' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/FileReader.php', 'PhpCsFixer\\FileRemoval' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/FileRemoval.php', 'PhpCsFixer\\Finder' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Finder.php', @@ -333,6 +335,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\ArrayNotation\\WhitespaceAfterCommaInArrayFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php', 'PhpCsFixer\\Fixer\\ArrayNotation\\YieldFromArrayToYieldsFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php', 'PhpCsFixer\\Fixer\\AttributeNotation\\AttributeEmptyParenthesesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/AttributeEmptyParenthesesFixer.php', + 'PhpCsFixer\\Fixer\\AttributeNotation\\OrderedAttributesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php', 'PhpCsFixer\\Fixer\\Basic\\BracesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php', 'PhpCsFixer\\Fixer\\Basic\\BracesPositionFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php', 'PhpCsFixer\\Fixer\\Basic\\CurlyBracesPositionFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/CurlyBracesPositionFixer.php', @@ -340,6 +343,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\Basic\\NoMultipleStatementsPerLineFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoMultipleStatementsPerLineFixer.php', 'PhpCsFixer\\Fixer\\Basic\\NoTrailingCommaInSinglelineFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoTrailingCommaInSinglelineFixer.php', 'PhpCsFixer\\Fixer\\Basic\\NonPrintableCharacterFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NonPrintableCharacterFixer.php', + 'PhpCsFixer\\Fixer\\Basic\\NumericLiteralSeparatorFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/NumericLiteralSeparatorFixer.php', 'PhpCsFixer\\Fixer\\Basic\\OctalNotationFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/OctalNotationFixer.php', 'PhpCsFixer\\Fixer\\Basic\\PsrAutoloadingFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/PsrAutoloadingFixer.php', 'PhpCsFixer\\Fixer\\Basic\\SingleLineEmptyBodyFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Basic/SingleLineEmptyBodyFixer.php', @@ -414,6 +418,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\DoctrineAnnotation\\DoctrineAnnotationBracesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationBracesFixer.php', 'PhpCsFixer\\Fixer\\DoctrineAnnotation\\DoctrineAnnotationIndentationFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationIndentationFixer.php', 'PhpCsFixer\\Fixer\\DoctrineAnnotation\\DoctrineAnnotationSpacesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationSpacesFixer.php', + 'PhpCsFixer\\Fixer\\ExperimentalFixerInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/ExperimentalFixerInterface.php', 'PhpCsFixer\\Fixer\\FixerInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/FixerInterface.php', 'PhpCsFixer\\Fixer\\FunctionNotation\\CombineNestedDirnameFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/CombineNestedDirnameFixer.php', 'PhpCsFixer\\Fixer\\FunctionNotation\\DateTimeCreateFromFormatCallFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php', @@ -449,6 +454,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\Import\\SingleImportPerStatementFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleImportPerStatementFixer.php', 'PhpCsFixer\\Fixer\\Import\\SingleLineAfterImportsFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleLineAfterImportsFixer.php', 'PhpCsFixer\\Fixer\\Indentation' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Indentation.php', + 'PhpCsFixer\\Fixer\\LanguageConstruct\\ClassKeywordFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordFixer.php', 'PhpCsFixer\\Fixer\\LanguageConstruct\\ClassKeywordRemoveFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordRemoveFixer.php', 'PhpCsFixer\\Fixer\\LanguageConstruct\\CombineConsecutiveIssetsFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php', 'PhpCsFixer\\Fixer\\LanguageConstruct\\CombineConsecutiveUnsetsFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveUnsetsFixer.php', @@ -498,6 +504,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\PhpTag\\FullOpeningTagFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/FullOpeningTagFixer.php', 'PhpCsFixer\\Fixer\\PhpTag\\LinebreakAfterOpeningTagFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/LinebreakAfterOpeningTagFixer.php', 'PhpCsFixer\\Fixer\\PhpTag\\NoClosingTagFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/NoClosingTagFixer.php', + 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitAttributesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php', 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitConstructFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php', 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderNameFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php', 'PhpCsFixer\\Fixer\\PhpUnit\\PhpUnitDataProviderReturnTypeFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderReturnTypeFixer.php', @@ -528,9 +535,11 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocAddMissingParamAnnotationFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocAlignFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAlignFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocAnnotationWithoutDotFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php', + 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocArrayTypeFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocIndentFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocIndentFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocInlineTagNormalizerFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocInlineTagNormalizerFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocLineSpanFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocLineSpanFixer.php', + 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocListTypeFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocListTypeFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocNoAccessFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoAccessFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocNoAliasTagFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoAliasTagFixer.php', 'PhpCsFixer\\Fixer\\Phpdoc\\PhpdocNoEmptyReturnFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoEmptyReturnFixer.php', @@ -566,11 +575,14 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Fixer\\Strict\\StrictParamFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Strict/StrictParamFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\EscapeImplicitBackslashesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/EscapeImplicitBackslashesFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\ExplicitStringVariableFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/ExplicitStringVariableFixer.php', + 'PhpCsFixer\\Fixer\\StringNotation\\HeredocClosingMarkerFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocClosingMarkerFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\HeredocToNowdocFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocToNowdocFixer.php', + 'PhpCsFixer\\Fixer\\StringNotation\\MultilineStringToHeredocFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/MultilineStringToHeredocFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\NoBinaryStringFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/NoBinaryStringFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\NoTrailingWhitespaceInStringFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/NoTrailingWhitespaceInStringFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\SimpleToComplexStringVariableFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SimpleToComplexStringVariableFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\SingleQuoteFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SingleQuoteFixer.php', + 'PhpCsFixer\\Fixer\\StringNotation\\StringImplicitBackslashesFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringImplicitBackslashesFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\StringLengthToEmptyFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringLengthToEmptyFixer.php', 'PhpCsFixer\\Fixer\\StringNotation\\StringLineEndingFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/StringLineEndingFixer.php', 'PhpCsFixer\\Fixer\\Whitespace\\ArrayIndentationFixer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/ArrayIndentationFixer.php', @@ -611,6 +623,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\PregException' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/PregException.php', 'PhpCsFixer\\RuleSet\\AbstractMigrationSetDescription' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/AbstractMigrationSetDescription.php', 'PhpCsFixer\\RuleSet\\AbstractRuleSetDescription' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/AbstractRuleSetDescription.php', + 'PhpCsFixer\\RuleSet\\DeprecatedRuleSetDescriptionInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/DeprecatedRuleSetDescriptionInterface.php', 'PhpCsFixer\\RuleSet\\RuleSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php', 'PhpCsFixer\\RuleSet\\RuleSetDescriptionInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetDescriptionInterface.php', 'PhpCsFixer\\RuleSet\\RuleSetInterface' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetInterface.php', @@ -637,6 +650,8 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\RuleSet\\Sets\\PHP80MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP80MigrationSet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHP81MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP81MigrationSet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHP82MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP82MigrationSet.php', + 'PhpCsFixer\\RuleSet\\Sets\\PHP83MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php', + 'PhpCsFixer\\RuleSet\\Sets\\PHP84MigrationSet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHPUnit100MigrationRiskySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHPUnit100MigrationRiskySet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHPUnit30MigrationRiskySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHPUnit30MigrationRiskySet.php', 'PhpCsFixer\\RuleSet\\Sets\\PHPUnit32MigrationRiskySet' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHPUnit32MigrationRiskySet.php', @@ -670,6 +685,7 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Tokenizer\\Analyzer\\AlternativeSyntaxAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/AlternativeSyntaxAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\AbstractControlCaseStructuresAnalysis' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AbstractControlCaseStructuresAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\ArgumentAnalysis' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/ArgumentAnalysis.php', + 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\AttributeAnalysis' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AttributeAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\CaseAnalysis' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/CaseAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\DataProviderAnalysis' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DataProviderAnalysis.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\Analysis\\DefaultAnalysis' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DefaultAnalysis.php', @@ -693,9 +709,11 @@ class ComposerStaticInit432d9322d3d4193d52e9a1d1ec2ff418 'PhpCsFixer\\Tokenizer\\Analyzer\\NamespacesAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespacesAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\RangeAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/RangeAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\ReferenceAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/ReferenceAnalyzer.php', + 'PhpCsFixer\\Tokenizer\\Analyzer\\SwitchAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/SwitchAnalyzer.php', 'PhpCsFixer\\Tokenizer\\Analyzer\\WhitespacesAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/WhitespacesAnalyzer.php', 'PhpCsFixer\\Tokenizer\\CT' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/CT.php', 'PhpCsFixer\\Tokenizer\\CodeHasher' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/CodeHasher.php', + 'PhpCsFixer\\Tokenizer\\Processor\\ImportProcessor' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Processor/ImportProcessor.php', 'PhpCsFixer\\Tokenizer\\Token' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Token.php', 'PhpCsFixer\\Tokenizer\\Tokens' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/Tokens.php', 'PhpCsFixer\\Tokenizer\\TokensAnalyzer' => __DIR__ . '/..' . '/friendsofphp/php-cs-fixer/src/Tokenizer/TokensAnalyzer.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 0d885716..4e0fc2be 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -229,57 +229,57 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.38.2", - "version_normalized": "3.38.2.0", + "version": "v3.56.1", + "version_normalized": "3.56.1.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "d872cdd543797ade030aaa307c0a4954a712e081" + "reference": "69c6168ae8bc96dc656c7f6c7271120a68ae5903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d872cdd543797ade030aaa307c0a4954a712e081", - "reference": "d872cdd543797ade030aaa307c0a4954a712e081", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/69c6168ae8bc96dc656c7f6c7271120a68ae5903", + "reference": "69c6168ae8bc96dc656c7f6c7271120a68ae5903", "shasum": "" }, "require": { - "composer/semver": "^3.3", + "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0 || ^5.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.27", - "symfony/polyfill-php80": "^1.27", - "symfony/polyfill-php81": "^1.27", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { "facile-it/paraunit": "^1.3 || ^2.0", + "infection/infection": "^0.27.11", "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.0", + "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.5.3", + "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.16", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "symfony/phpunit-bridge": "^6.2.3", - "symfony/yaml": "^5.4 || ^6.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "ext-dom": "For handling output formats in XML", "ext-mbstring": "For handling non-UTF8 characters." }, - "time": "2023-11-14T00:19:22+00:00", + "time": "2024-05-10T11:31:15+00:00", "bin": [ "php-cs-fixer" ], @@ -313,7 +313,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.38.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.56.1" }, "funding": [ { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 6b189188..8673d086 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => '6e4343516f2667323b3b38369ea21e52d3a47f8e', + 'reference' => '251d9aaa81bc6cbf0d1b00e1a0becc40f608e8d0', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-main', 'version' => 'dev-main', - 'reference' => '6e4343516f2667323b3b38369ea21e52d3a47f8e', + 'reference' => '251d9aaa81bc6cbf0d1b00e1a0becc40f608e8d0', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -47,9 +47,9 @@ 'dev_requirement' => false, ), 'friendsofphp/php-cs-fixer' => array( - 'pretty_version' => 'v3.38.2', - 'version' => '3.38.2.0', - 'reference' => 'd872cdd543797ade030aaa307c0a4954a712e081', + 'pretty_version' => 'v3.56.1', + 'version' => '3.56.1.0', + 'reference' => '69c6168ae8bc96dc656c7f6c7271120a68ae5903', 'type' => 'application', 'install_path' => __DIR__ . '/../friendsofphp/php-cs-fixer', 'aliases' => array(), diff --git a/vendor/friendsofphp/php-cs-fixer/CHANGELOG.md b/vendor/friendsofphp/php-cs-fixer/CHANGELOG.md index 1ddea429..1c790833 100644 --- a/vendor/friendsofphp/php-cs-fixer/CHANGELOG.md +++ b/vendor/friendsofphp/php-cs-fixer/CHANGELOG.md @@ -3,6 +3,437 @@ CHANGELOG for PHP CS Fixer This file contains changelogs for stable releases only. +Changelog for v3.56.1 +--------------------- + +* chore: improve PHPDoc typehints (#7994) +* CI: Allow any integer in PHPStan error for Token's constructor (#8000) +* fix: Better array shape in `PhpUnitDedicateAssertFixer` (#7999) +* fix: `ConstantCaseFixer` - do not touch typed constants (#7998) + +Changelog for v3.56.0 +--------------------- + +* feat: `TrailingCommaInMultilineFixer` - handle trailing comma in language constructs (#7989) +* fix: `TrailingCommaInMultilineFixer` - language constructs should be covered by arguments, not parameters (#7990) +* chore: remove invalid comment (#7987) +* DX: Cache optimisation (#7985) + +Changelog for v3.55.0 +--------------------- + +* feat: Introduce `OrderedAttributesFixer` (#7395) +* chore: few SCA fixes and dev-tools update (#7969) +* chore: fix phpdoc types (#7977) +* chore: narrow PHPDoc types (#7979) +* chore: Normalize implicit backslahes in single quoted strings internally (#7786) +* chore: phpdoc - rely on strict list/tuple/assoc instead of array (#7978) +* chore: PhpUnitDataProviderNameFixer - follow config creation pattern (#7980) +* chore: Preg - drop half-support for array-pattern (#7976) +* chore: re-use CodeHasher (#7984) +* chore: RuleSetsTest - assert that Fixer is configurable (#7961) +* chore: sugar syntax (#7986) +* chore: Tokens should be always a list (#7698) +* CI: Ad-hoc fix for MacOS jobs (#7970) +* CI: Fix calculating diff between branches in PRs (#7973) +* DX: allow to enforce cache mechanism by env var (#7983) +* DX: do not typehint fixed-length arrays as lists (#7974) +* DX: Prevent having deprecated fixers listed as successors of other deprecated fixers (#7967) +* DX: Resolve/Ignore PHPStan issues on level 6 + bump to level 7 with new baseline (#7971) +* DX: use `list` type in PHPDoc (#7975) +* fix: `PhpUnitAttributesFixer` - fix for `#[RequiresPhp]` exceeding its constructor parameters (#7966) +* test: don't count comment after class as another classy element (#7982) + +Changelog for v3.54.0 +--------------------- + +* feat: introduce `PhpUnitAttributesFixer` (#7831) +* chore: Properly determine self-approval trigger commit (#7936) +* chore: Revert ref for self-approval Git checkout (#7944) +* CI: check if proper array key is declared (#7912) +* DX: cleanup `FullyQualifiedStrictTypesFixerTest` (#7954) +* DX: cleanup `PhpdocNoAccessFixerTest` (#7933) +* DX: cleanup `PhpUnitMethodCasingFixerTest` (#7948) +* DX: cleanup `PhpUnitStrictFixerTest` (#7938) +* DX: Improve internal dist config for Fixer (#7952) +* DX: Improve issue templates (#7942) +* DX: there is no namespace if there is no PHP code (#7953) +* DX: update .gitattributes (#7931) +* fix: Remove Infection during Docker release (#7937) +* fix: `FullyQualifiedStrictTypesFixer` - do not add imports before PHP opening tag (#7955) +* fix: `PhpUnitMethodCasingFixer` - do not double underscore (#7949) +* fix: `PhpUnitTestClassRequiresCoversFixer` - do not add annotation when there are attributes (#7880) +* test: Ignore PHP version related mutations (#7935) + +Changelog for v3.53.0 +--------------------- + +* chore: Use `list` over `array` in more places (#7905) +* CI: allow for self-approvals for maintainers (#7921) +* CI: Improve Infection setup (#7913) +* CI: no need to trigger enable auto-merge when self-approve (#7929) +* DX: reduce `array_filter` function usages (#7923) +* DX: remove duplicated character from `trim` call (#7930) +* DX: update actions producing warnings (#7925) +* DX: update actions producing warnings (#7928) +* DX: update `phpstan/phpstan-strict-rules` (#7924) +* feat: Add trailing comma in multiline to PER-CS 2.0 (#7916) +* feat: Introduce `AttributeAnalysis` (#7909) +* feat: `@PHP84Migration` introduction (#7774) +* fix: Constant invocation detected in typed constants (#7892) +* fix: `PhpdocArrayTypeFixer` - JIT stack limit exhausted (#7895) +* test: Introduce Infection for mutation tests (#7874) + +Changelog for v3.52.1 +--------------------- + +* fix: StatementIndentationFixer - do not crash on ternary operator in class property (#7899) +* fix: `PhpCsFixer\Tokenizer\Tokens::setSize` return type (#7900) + +Changelog for v3.52.0 +--------------------- + +* chore: fix PHP 8.4 deprecations (#7894) +* chore: fix PHPStan 1.10.60 issues (#7873) +* chore: list over array in more places (#7876) +* chore: replace template with variable in Preg class (#7882) +* chore: update PHPStan (#7871) +* depr: `nullable_type_declaration_for_default_null_value` - deprecate option that is against `@PHP84Migration` (#7872) +* docs: Fix typo (#7889) +* feat: Add support for callable template in PHPDoc parser (#7084) +* feat: Add `array_indentation` to `PER-CS2.0` ruleset (#7881) +* feat: `@Symfony:risky` - add `no_unreachable_default_argument_value` (#7863) +* feat: `PhpCsFixer` ruleset - enable `nullable_type_declaration_for_default_null_value` (#7870) +* fix: Constant invocation detected in DNF types (#7869) +* fix: Correctly indent multiline constants and properties (#7875) +* fix: `no_useless_concat_operator` - do not break variable (#7827) +* fix: `TokensAnalyzer` - handle unary operator in arrow functions (#7862) +* fix: `TypeExpression` - fix "JIT stack limit exhausted" error (#7843) + +Changelog for v3.51.0 +--------------------- + +* chore: add missing tests for non-documentation classes (#7848) +* chore: do not perform type analysis in tests (#7852) +* chore: list over array in more places (#7857) +* chore: tests documentation classes (#7855) +* feat: `@Symfony` - add nullable_type_declaration (#7856) +* test: fix wrong type in param annotation (#7858) + +Changelog for v3.50.0 +--------------------- + +* chore: add missing types (#7842) +* chore: BlocksAnalyzer - raise exception on invalid index (#7819) +* chore: DataProviderAnalysis - expect list over array (#7800) +* chore: do not use `@large` on method level (#7832) +* chore: do not use `@medium` on method level (#7833) +* chore: Fix typos (#7835) +* chore: rename variables (#7847) +* chore: some improvements around array typehints (#7799) +* CI: fix PHP 8.4 job (#7829) +* DX: Include `symfony/var-dumper` in dev tools (#7795) +* feat: Ability to remove unused imports from multi-use statements (#7815) +* feat: allow PHPUnit 11 (#7824) +* feat: Allow shortening symbols from multi-use statements (only classes for now) (#7816) +* feat: introduce `PhpdocArrayTypeFixer` (#7812) +* feat: PhpUnitTestCaseStaticMethodCallsFixer - cover PHPUnit v11 methods (#7822) +* feat: Support for multi-use statements in `NamespaceUsesAnalyzer` (#7814) +* feat: `MbStrFunctionsFixer` - add support for `mb_trim`, `mb_ltrim` and `mb_rtrim` functions (#7840) +* feat: `NoEmptyPhpdocFixer` - do not leave empty line after removing PHPDoc (#7820) +* feat: `no_superfluous_phpdoc_tags` - introduce `allow_future_params` option (#7743) +* fix: do not use wrongly named arguments in data providers (#7823) +* fix: Ensure PCNTL extension is always installed in Docker (#7782) +* fix: PhpdocListTypeFixer - support key types containing `<…>` (#7817) +* fix: Proper build target for local Docker Compose (#7834) +* fix: union PHPDoc support in `fully_qualified_strict_types` fixer (#7719) +* fix: `ExecutorWithoutErrorHandler` - remove invalid PHP 7.4 type (#7845) +* fix: `fully_qualified_strict_types` must honor template/local type identifiers (#7724) +* fix: `MethodArgumentSpaceFixer` - do not break heredoc/nowdoc (#7828) +* fix: `NumericLiteralSeparatorFixer` - do not change `float` to `int` when there is nothing after the dot (#7805) +* fix: `PhpUnitStrictFixer` - do not crash on property having the name of method to fix (#7804) +* fix: `SingleSpaceAroundConstructFixer` - correctly recognise multiple constants (#7700) +* fix: `TypeExpression` - handle array shape key with dash (#7841) + +Changelog for v3.49.0 +--------------------- + +* chore(checkbashisms): update to 2.23.7 (#7780) +* chore: add missing key types in PHPDoc types (#7779) +* chore: Exclude `topic/core` issues/PRs from Stale Bot (#7788) +* chore: `DescribeCommand` - better handling of deprecations (#7778) +* docs: docker - use gitlab reporter in GitLab integration example (#7764) +* docs: docker in CI - don't suggest command that overrides path from config file (#7763) +* DX: check deprecations exactly (#7742) +* feat: Add `ordered_types` to `@Symfony` (#7356) +* feat: introduce `PhpdocListTypeFixer` (#7796) +* feat: introduce `string_implicit_backslashes` as `escape_implicit_backslashes` replacement (#7669) +* feat: update `Symfony.nullable_type_declaration_for_default_null_value` config (#7773) +* feat: `@PhpCsFixer` ruleset - enable `php_unit_data_provider_static` (#7685) +* fix: Allow using cache when running in Docker distribution (#7769) +* fix: ClassDefinitionFixer for anonymous class with phpdoc/attribute on separate line (#7546) +* fix: `ClassKeywordFixer` must run before `FullyQualifiedStrictTypesFixer` (#7767) +* fix: `function_to_constant` `get_class()` replacement (#7770) +* fix: `LowercaseStaticReferenceFixer` - do not change typed constants (#7775) +* fix: `PhpdocTypesFixer` - handle more complex types (#7791) +* fix: `TypeExpression` - do not break type using `walkTypes` method (#7785) + +Changelog for v3.48.0 +--------------------- + +* chore: `FullyQualifiedStrictTypesFixer` must run before `OrderedInterfacesFixer` (#7762) +* docs: Add PHP-CS-Fixer integration in a GitHub Action step (#7757) +* feat: `PhpdocTypesOrderFixer` Support DNF types (#7732) +* fix: Support shebang in fixers operating on PHP opening tag (#7687) +* fix: work correctly for a switch/case with ternary operator (#7756) +* fix: `NoUselessConcatOperatorFixer` - do not remove new line (#7759) + +Changelog for v3.47.1 +--------------------- + +* fix: Do not override short name with relative reference (#7752) +* fix: make `BinaryOperatorSpacesFixer` work as pre-v3.47 (#7751) +* fix: Proper Docker image name suffix (#7739) +* fix: `FullyQualifiedStrictTypesFixer` - do not change case of the symbol when there's name collision between imported class and imported function (#7750) +* fix: `FullyQualifiedStrictTypesFixer` - do not modify statements with property fetch and `::` (#7749) + +Changelog for v3.47.0 +--------------------- + +* chore: better identify EXPERIMENTAL rules (#7729) +* chore: fix issue detected by unlocked PHPStan + upgrade dev-tools (#7678) +* chore: handle extract() (#7684) +* chore: Mention contributors in app info (#7668) +* chore: no need to mark private methods as internal (#7715) +* chore: ProjectCodeTests - dry for function usage extractions (#7690) +* chore: reduce PHPStan baseline (#7644) +* chore: use numeric literal separator for PHP version IDs (#7712) +* chore: use numeric_literal_separator for project (#7713) +* chore: Utils::sortElements - better typing (#7646) +* CI: Allow running Stale Bot on demand (#7711) +* CI: Fix PHP 8.4 (#7702) +* CI: Give write permissions to Stale Bot (#7716) +* CI: Use `actions/stale` v9 (#7710) +* docs: Add information about allowing maintainers to update PRs (#7683) +* docs: CONTRIBUTING.md - update Opening a PR (#7691) +* docs: Display/include tool info/version by default in commands and reports (#7733) +* DX: fix deprecation tests warnings for PHP 7.4 (#7725) +* DX: update `host.docker.internal` in Compose override template (#7661) +* DX: `NumericLiteralSeparatorFixer` - change default strategy to `use_separator` (#7730) +* feat: Add support for official Docker images of Fixer (#7555) +* feat: Add `spacing` option to `PhpdocAlignFixer` (#6505) +* feat: Add `union_types` option to `phpdoc_to_param_type`, `phpdoc_to_property_type`, and `phpdoc_to_return_type` fixers (#7672) +* feat: Introduce `heredoc_closing_marker` fixer (#7660) +* feat: Introduce `multiline_string_to_heredoc` fixer (#7665) +* feat: Introduce `NumericLiteralSeparatorFixer` (#6761) +* feat: no_superfluous_phpdoc_tags - support for arrow function (#7666) +* feat: Simplify closing marker when possible in `heredoc_closing_marker` fixer (#7676) +* feat: Support typed properties and attributes in `fully_qualified_strict_types` (#7659) +* feat: `@PhpCsFixer` ruleset - enable no_whitespace_before_comma_in_array.after_heredoc (#7670) +* fix: Improve progress bar visual layer (#7708) +* fix: indentation of control structure body without braces (#7663) +* fix: make sure all PHP extensions required by PHPUnit are installed (#7727) +* fix: PhpdocToReturnTypeFixerTest - support for arrow functions (#7645) +* fix: Several improvements for `fully_qualified_strict_types` (respect declared symbols, relative imports, leading backslash in global namespace) (#7679) +* fix: SimplifiedNullReturnFixer - support array return typehint (#7728) +* fix: Support numeric values without leading zero in `numeric_literal_separator` (#7735) +* fix: `BinaryOperatorSpacesFixer` - align correctly when multiple shifts occurs in single line (#7593) +* fix: `ClassReferenceNameCasingFixer` capitalizes the property name after the nullsafe operator (#7696) +* fix: `fully_qualified_strict_types` with `leading_backslash_in_global_namespace` enabled - handle reserved types in phpDoc (#7648) +* fix: `NoSpaceAroundDoubleColonFixer` must run before `MethodChainingIndentationFixer` (#7723) +* fix: `no_superfluous_phpdoc_tags` must honor multiline docs (#7697) +* fix: `numeric_literal_separator` - Handle zero-leading floats properly (#7737) +* refactor: increase performance by ~7% thanks to `Tokens::block*Cache` hit increased by ~12% (#6176) +* refactor: Tokens - fast check for non-block in 'detectBlockType', evaluate definitions only once in 'getBlockEdgeDefinitions' (#7655) +* refactor: `Tokens::clearEmptyTokens` - play defensive with cache clearing (#7658) +* test: ensure we do not forget to test any short_open_tag test (#7638) + +Changelog for v3.46.0 +--------------------- + +* chore: fix internal typehints in Tokens (#7656) +* chore: reduce PHPStan baseline (#7643) +* docs: Show class with unit tests and BC promise info (#7667) +* feat: change default ruleset to `@PER-CS` (only behind PHP_CS_FIXER_FUTURE_MODE=1) (#7650) +* feat: Support new/instanceof/use trait in `fully_qualified_strict_types` (#7653) +* fix: FQCN parse phpdoc using full grammar regex (#7649) +* fix: Handle FQCN properly with `leading_backslash_in_global_namespace` option enabled (#7654) +* fix: PhpdocToParamTypeFixerTest - support for arrow functions (#7647) +* fix: PHP_CS_FIXER_FUTURE_MODE - proper boolean validation (#7651) + +Changelog for v3.45.0 +--------------------- + +* feat: Enable symbol importing in `@PhpCsFixer` ruleset (#7629) +* fix: NoUnneededBracesFixer - improve handling of global namespace (#7639) +* test: run tests with "short_open_tag" enabled (#7637) + +Changelog for v3.44.0 +--------------------- + +* feat: Introduce percentage bar as new default progress output (#7603) + +Changelog for v3.43.1 +--------------------- + +* fix: Import only unique symbols' short names (#7635) + +Changelog for v3.43.0 +--------------------- + +* chore: change base of `@Symfony` set to `@PER-CS2.0` (#7627) +* chore: PHPUnit - allow for v10 (#7606) +* chore: Preg - rework catching the error (#7616) +* chore: Revert unneeded peer-dep-pin and re-gen lock file (#7618) +* docs: drop extra note about 8.0.0 bug in README.md (#7614) +* feat: add cast_spaces into `@PER-CS2.0` (#7625) +* feat: Configurable phpDoc tags for FQCN processing (#7628) +* feat: StatementIndentationFixer - introduce stick_comment_to_next_continuous_control_statement config (#7624) +* feat: UnaryOperatorSpacesFixer - introduce only_dec_inc config (#7626) +* fix: FullyQualifiedStrictTypesFixer - better support annotations in inline {} (#7633) +* fix: Improve how FQCN is handled in phpDoc (#7622) +* fix: phpdoc_align - fix multiline tag alignment issue (#7630) + +Changelog for v3.42.0 +--------------------- + +* chore: aim to not rely on internal array pointer but use array_key_first (#7613) +* chore: deprecate Token::isKeyCaseSensitive (#7599) +* chore: deprecate Token::isKeyCaseSensitive, 2nd part (#7601) +* chore: do not check PHP_VERSION_ID (#7602) +* chore: FileFilterIteratorTest - more accurate type in docs (#7542) +* chore: minor code cleanup (#7607) +* chore: more types (#7598) +* chore: PHPDoc key-value spacing (#7592) +* chore: PHPUnit - run defects first (#7570) +* chore: ProjectCodeTest - DRY on Tokens creation (#7574) +* chore: ProjectCodeTest - prepare for symfony/console v7 (#7605) +* chore: ProjectCodeTest::provide*ClassCases to return iterable with key for better tests execution log (#7572) +* chore: ProjectCodeTest::testDataProvidersDeclaredReturnType - use better DataProvider to simplify test logic (#7573) +* chore: TokensAnalyzer - string-enum for better typehinting (#7571) +* chore: unify tests not agnostic of PHP version (#7581) +* chore: use ::class more (#7545) +* CI: Introduce `composer-unused` (#7536) +* DX: add types to anonymous functions (#7561) +* DX: Allow running smoke tests within Docker runtime (#7608) +* DX: check fixer's options for wording (#7543) +* DX: cleanup deprecation message (#7576) +* DX: do not allow overriding constructor of `PHPUnit\Framework\TestCase` (#7563) +* DX: do not import ExpectDeprecationTrait in UtilsTest (#7562) +* DX: Enforce consistent naming in tests (#7556) +* DX: fix checking test class extends `PhpCsFixer\Tests\TestCase` (#7567) +* DX: make sure that exceptions in `AbstractFixerTestCase::testProperMethodNaming` are not already fixed (#7588) +* DX: remove recursion from AbstractIntegrationTestCase::testIntegration (#7577) +* DX: remove `PhpUnitNamespacedFixerTest::testClassIsFixed` (#7564) +* DX: remove `symfony/phpunit-bridge` (#7578) +* DX: replace fixture classes with anonymous ones (#7533) +* DX: Unify Docker mount points and paths (#7549) +* DX: unify fixer's test method names - quick wins (#7584) +* DX: unify tests for casing fixers (#7558) +* DX: use anonymous function over concrete classes (#7553) +* feat(EXPERIMENTAL): ClassKeywordFixer (#2918) +* feat(EXPERIMENTAL): ClassKeywordFixer, part 2 (#7550) +* feat(PhpdocToCommentFixer): Add option to handle return as valid docblock usage (#7401) (#7402) +* feat: Ability to import FQCNs found during analysis (#7597) +* feat: add phpDoc support for `fully_qualified_strict_types` fixer (#5620) +* feat: Handle deprecated rule sets similarly to deprecated fixers (#7288) +* feat: PhpUnitTestCaseStaticMethodCallsFixer - cover PHPUnit v10 methods (#7604) +* feat: Support more FQCNs cases in `fully_qualified_strict_types` (#7459) +* fix: AbstractFixerTestCase - fix checking for correct casing (#7540) +* fix: Better OS detection in integration tests (#7547) +* fix: NativeTypeDeclarationCasingFixe - handle static property without type (#7589) +* test: AutoReview - unify data provider returns (#7544) +* test: check to have DataProviders code agnostic of PHP version (#7575) + +Changelog for v3.41.1 +--------------------- + +* DX: Change `@testWith` to `@dataProvider` (#7535) +* DX: Introduce Markdownlint (#7534) +* fix: NativeTypeDeclarationCasingFixer - do not crash on `var` keyword (#7538) + +Changelog for v3.41.0 +--------------------- + +* chore: Move `mb_str_functions` PHP 8.3 cases to separate test (#7505) +* chore: Symfony v7 is now stable (#7469) +* CI: drop PHP 8.3 hacks (#7519) +* docs: Improve docs for `no_spaces_after_function_name` (#7520) +* DX: Ability to run Sphinx linter locally (#7481) +* DX: AbstractFixerTest - use anonymous classes (#7527) +* DX: Add progress output for `cs:check` script (#7514) +* DX: align doubles naming (#7525) +* DX: remove AbstractFixerTestCase::getTestFile() (#7495) +* DX: remove jangregor/phpstan-prophecy (#7524) +* DX: remove Prophecy (#7509) +* DX: replace Prophecy with anonymous classes in CacheTest (#7503) +* DX: replace Prophecy with anonymous classes in ProcessLintingResultTest (#7501) +* DX: Utilise auto-discovery for PHPStan formatter (#7490) +* feat: Support `mb_str_pad` function in `mb_str_functions` rule (#7499) +* fix: BinaryOperatorSpacesFixer - do not add whitespace inside short function (#7523) +* fix: Downgrade PDepend to version not supporting Symfony 7 (#7513) +* fix: GlobalNamespaceImportFixer - key in PHPDoc's array shape matching class name (#7522) +* fix: SpacesInsideParenthesesFixer - handle class instantiation parentheses (#7531) +* Update PHPstan to 1.10.48 (#7532) + +Changelog for v3.40.2 +--------------------- + +* docs: fix link to source classes (#7493) + +Changelog for v3.40.1 +--------------------- + +* chore: Delete stray file x (#7473) +* chore: Fix editorconfig (#7478) +* chore: Fix typos (#7474) +* chore: Fix YAML line length (#7476) +* chore: Indent JSON files with 4 spaces (#7480) +* chore: Make YAML workflow git-based (#7477) +* chore: Use stable XDebug (#7489) +* CI: Lint docs (#7479) +* CI: Use PHPStan's native Github error formatter (#7487) +* DX: fix PHPStan error (#7488) +* DX: PsrAutoloadingFixerTest - do not build mock in data provider (#7491) +* DX: PsrAutoloadingFixerTest - merge all data providers into one (#7492) +* DX: Update PHPStan to 1.10.46 (#7486) +* fix: `NoSpacesAfterFunctionNameFixer` - do not remove space if the opening parenthesis part of an expression (#7430) + +Changelog for v3.40.0 +--------------------- + +* chore: officially support PHP 8.3 (#7466) +* chore: update deps (#7471) +* CI: add --no-update while dropping non-compat `facile-it/paraunit` (#7470) +* CI: automate --ignore-platform-req=PHP (#7467) +* CI: bump actions/github-script to v7 (#7468) +* CI: move humbug/box out of dev-tools/composer.json (#7472) + +Changelog for v3.39.1 +--------------------- + +* DX: introduce SwitchAnalyzer (#7456) +* fix: NoExtraBlankLinesFixer - do not remove blank line after `? : throw` (#7457) +* fix: OrderedInterfacesFixer - do not comment out interface (#7464) +* test: Improve `ExplicitIndirectVariableFixerTest` (#7451) + +Changelog for v3.39.0 +--------------------- + +* chore: Add support for Symfony 7 (#7453) +* chore: IntegrationTest - move support of php< requirement to main Integration classes (#7448) +* CI: drop Symfony ^7 incompat exceptions of php-coveralls and cli-executor (#7455) +* CI: early compatibility checks with Symfony 7 (#7431) +* docs: drop list.rst and code behind it (#7436) +* docs: remove Gitter mentions (#7441) +* DX: Ability to run Fixer on PHP8.3 for development (#7449) +* DX: describe command - for rules, list also sets that are including them (#7419) +* DX: Docker clean up (#7450) +* DX: more usage of spaceship operator (#7438) +* DX: Put `Preg`'s last error message in exception message (#7443) +* feat: Introduce `@PHP83Migration` ruleset and PHP 8.3 integration test (#7439) +* test: Improve `AbstractIntegrationTestCase` description (#7452) + Changelog for v3.38.2 --------------------- @@ -216,7 +647,7 @@ Changelog for v3.23.0 --------------------- * bug: BlankLineBeforeStatementFixer - do not enforce/add a blank line when there is a blank line between the comment and the statement already (#7190) -* bug: Fix detecting classy invokation in catch (#7191) +* bug: Fix detecting classy invocation in catch (#7191) * bug: Fix names resolving in `no_superfluous_phpdoc_tags` fixer (#7189) * bug: Fix various bugs in `FullyQualifiedStrictTypesFixer` fixer (#7188) * bug: Fixed line between general script documentation and require (#7177) @@ -645,7 +1076,7 @@ Changelog for v3.11.0 * bug: Fix MethodChainingIndentationFixer with arrow functions and class instantiation (#5587) * bug: MethodChainingIndentationFixer - Fix bug with attribute access (#6573) * bug: NoMultilineWhitespaceAroundDoubleArrowFixer - fix for single line comment (#6589) -* bug: TypeAlternationTransformer - TypeIntersectionTransforme - Bug: handle attributes (#6579) +* bug: TypeAlternationTransformer - TypeIntersectionTransformer - Bug: handle attributes (#6579) * bug: [BinaryOperatorFixer] Fix more issues with scoped operators (#6559) * docs: Remove `$` from console command snippets (#6600) * docs: Remove `$` from console command snippets in documentation (#6599) @@ -704,7 +1135,7 @@ Changelog for v3.9.5 * DX: Narrow docblock types in Runner and Report (#6465) * DX: Narrow docblock types in Tokenizer (#6293) * minor: extract NoMultipleStatementsPerLineFixer from BracesFixer (#6458) -* minor: Let PhpdocLineSpan fixer detect docblocks when seperator from token with attribute (#6343) +* minor: Let PhpdocLineSpan fixer detect docblocks when separator from token with attribute (#6343) Changelog for v3.9.4 -------------------- @@ -786,7 +1217,7 @@ Changelog for v3.7.0 * bug #6112 [BinaryOperatorSpacesFixer] Fix align of `=` inside calls of methods (VincentLanglet) * bug #6279 ClassReferenceNameCasingFixer - Fix for double arrow (SpacePossum) -* bug #6280 Fix bunch of enum issus (SpacePossum) +* bug #6280 Fix bunch of enum issues (SpacePossum) * bug #6283 ClassReferenceNameCasingFixer - detect imports (SpacePossum) * feature #5892 NewWithBracesFixer - option to remove braces (jrmajor) * feature #6081 Allow multiline constructor arguments in an anonymous classes (jrmajor, SpacePossum) @@ -816,7 +1247,7 @@ Changelog for v3.6.0 * bug #6241 NoSuperfluousPhpdocTagsFixer - fix for reference and splat operator (kubawerlos) * bug #6243 PhpdocTypesOrderFixer - fix for intersection types (kubawerlos) * bug #6254 PhpUnitDedicateAssertFixer - remove `is_resource`. (drupol) -* bug #6264 TokensAnalyzer - fix isConstantInvocation detection for mulitple exce… (SpacePossum) +* bug #6264 TokensAnalyzer - fix isConstantInvocation detection for multiple exce… (SpacePossum) * bug #6265 NullableTypeDeclarationForDefaultNullValueFixer - handle "readonly" a… (SpacePossum) * bug #6266 SimplifiedIfReturnFixer - handle statement in loop without braces (SpacePossum) * feature #6262 ClassReferenceNameCasingFixer - introduction (SpacePossum) @@ -838,7 +1269,7 @@ Changelog for v3.5.0 * bug #6165 DeclareEqualNormalizeFixer - fix for declare having multiple directives (kubawerlos) * bug #6170 NonPrintableCharacterFixer - fix for string in single quotes, having non-breaking space, linebreak, and single quote inside (kubawerlos) * bug #6181 UseTransformer - Trait import in enum fix (PHP8.1) (SpacePossum) -* bug #6188 PhpdocTo(Param|Property|Return)TypeFixer - fix for type intersections (kubawerlos) +* bug #6188 `PhpdocTo(Param|Property|Return)TypeFixer` - fix for type intersections (kubawerlos) * bug #6202 SquareBraceTransformer - fix for destructing square brace after double arrow (kubawerlos) * bug #6209 OrderedClassElementsFixer - PHP8.0 support abstract private methods in traits (SpacePossum) * bug #6224 ArgumentsAnalyzer - support PHP8.1 readonly (SpacePossum) @@ -894,7 +1325,7 @@ Changelog for v3.4.0 * minor #6109 Add return type to `DummyTestSplFileInfo::getRealPath()` (derrabus) * minor #6115 Remove PHP 7.2 polyfill (derrabus) * minor #6116 CI: remove installation of mbstring polyfill in build script, it's required dependency now (keradus) -* minor #6119 OrderedClassElementsFixer - PHPUnit assert(Pre|Post)Conditions methods support (meyerbaptiste) +* minor #6119 OrderedClassElementsFixer - PHPUnit `assert(Pre|Post)Conditions` methods support (meyerbaptiste) * minor #6121 Use Tokens::ensureWhitespaceAtIndex to simplify code (kubawerlos) * minor #6127 Remove 2nd parameter to XdebugHandler constructor (phil-davis) * minor #6129 clean ups (SpacePossum) @@ -1017,7 +1448,7 @@ Changelog for v3.2.0 * minor #6029 PhpUnitDedicateAssertFixer - add "assertStringContainsString" and "as… (SpacePossum) * minor #6030 SingleSpaceAfterConstructFixer - Add `switch` support (SpacePossum) * minor #6033 ArgumentsAnalyzerTest - add more tests (SpacePossum) -* minor #6034 7.0|7.1 - cleanup tests (SpacePossum) +* minor #6034 Cleanup tests for PHP 7.0 and 7.1 (SpacePossum) * minor #6035 Documentation generation split up and add list. (SpacePossum) * minor #6048 Fix "can not" spelling (mvorisek) @@ -1476,7 +1907,7 @@ Changelog for v2.17.3 Changelog for v2.17.2 --------------------- -* bug #5345 CleanNamespaceFixer - preserve traling comments (SpacePossum) +* bug #5345 CleanNamespaceFixer - preserve trailing comments (SpacePossum) * bug #5348 PsrAutoloadingFixer - fix for class without namespace (kubawerlos) * bug #5362 SingleSpaceAfterConstructFixer: Do not adjust whitespace before multiple multi-line extends (localheinz, SpacePossum) * minor #5314 Enable testing with PHPUnit 9.x (sanmai) @@ -1574,7 +2005,6 @@ Changelog for v2.17.0 * minor #5323 NoUselessSprintfFixer - Fix test on PHP5.6 (SpacePossum) * minor #5326 DX: relax composer requirements to not block installation under PHP v8, support for PHP v8 is not yet ready (keradus) - Changelog for v2.16.10 ---------------------- @@ -2198,7 +2628,7 @@ Changelog for v2.15.4 * minor #4564 Move readme-update command to Section 3 (iwasherefirst2) * minor #4566 Update symfony ruleset (gharlan) * minor #4570 Command::execute() should always return an integer (derrabus) -* minor #4580 Add suport for true/false return type hints. (SpacePossum) +* minor #4580 Add support for true/false return type hints. (SpacePossum) * minor #4584 Increase PHPStan level to 1 (julienfalque) * minor #4585 Fix deprecation notices (julienfalque) * minor #4587 Output details - Explain why a file was skipped (SpacePossum) @@ -2359,8 +2789,8 @@ Changelog for v2.14.3 * minor #4340 Travis: build against 7.4snapshot instead of nightly (Slamdunk) * minor #4351 code grooming (SpacePossum) * minor #4353 Add more priority tests (SpacePossum) -* minor #4364 DX: MethodChainingIndentationFixer - remove unneccesary loop (Sijun Zhu) -* minor #4366 Unset the auxillary variable $a (GrahamCampbell) +* minor #4364 DX: MethodChainingIndentationFixer - remove unnecessary loop (Sijun Zhu) +* minor #4366 Unset the auxiliary variable $a (GrahamCampbell) * minor #4368 Fixed TypeShortNameResolverTest::testResolver (GrahamCampbell) * minor #4380 PHP7.4 - Add "str_split" => "mb_str_split" mapping. (SpacePossum) * minor #4381 PHP7.4 - Add support for magic methods (un)serialize. (SpacePossum) @@ -2534,7 +2964,7 @@ Changelog for v2.13.0 * feature #3812 Add FopenFlagOrderFixer & FopenFlagsFixer (SpacePossum) * feature #3826 Add CombineNestedDirnameFixer (gharlan) * feature #3833 BinaryOperatorSpacesFixer - Add "no space" fix strategy (SpacePossum) -* feature #3841 NoAliasFunctionsFixer - add opt in option for ext-mbstring aliasses (SpacePossum) +* feature #3841 NoAliasFunctionsFixer - add opt in option for ext-mbstring aliases (SpacePossum) * feature #3876 NativeConstantInvocationFixer - add the scope option (stof, keradus) * feature #3886 Add PhpUnitMethodCasingFixer (Slamdunk) * feature #3907 Add ImplodeCallFixer (kubawerlos) @@ -2615,8 +3045,8 @@ Changelog for v2.12.9 * minor #4340 Travis: build against 7.4snapshot instead of nightly (Slamdunk) * minor #4351 code grooming (SpacePossum) * minor #4353 Add more priority tests (SpacePossum) -* minor #4364 DX: MethodChainingIndentationFixer - remove unneccesary loop (Sijun Zhu) -* minor #4366 Unset the auxillary variable $a (GrahamCampbell) +* minor #4364 DX: MethodChainingIndentationFixer - remove unnecessary loop (Sijun Zhu) +* minor #4366 Unset the auxiliary variable $a (GrahamCampbell) * minor #4368 Fixed TypeShortNameResolverTest::testResolver (GrahamCampbell) * minor #4380 PHP7.4 - Add "str_split" => "mb_str_split" mapping. (SpacePossum) * minor #4393 DX: add missing explicit return types (kubawerlos) @@ -2871,7 +3301,7 @@ Changelog for v2.11.2 * bug #3673 PhpdocScalarFixer - Add "types" option (julienfalque, keradus) * bug #3674 YodaStyleFixer - Fix variable detection for multidimensional arrays (julienfalque, SpacePossum) * bug #3684 PhpUnitStrictFixer - Do not fix if not correct # of arguments are used (SpacePossum) -* bug #3708 EspaceImplicitBackslashesFixer - Fix escaping multiple backslashes (julienfalque) +* bug #3708 EscapeImplicitBackslashesFixer - Fix escaping multiple backslashes (julienfalque) * bug #3715 SingleImportPerStatementFixer - Fix handling whitespace before opening brace (julienfalque) * bug #3731 PhpdocIndentFixer - crash fix (SpacePossum) * bug #3755 YodaStyleFixer - handle space between var name and index (SpacePossum) @@ -3005,7 +3435,7 @@ Changelog for v2.10.3 * minor #3484 Create Tokens::findBlockStart (ntzm) * minor #3512 Add missing array typehints (ntzm) * minor #3513 Making AppVeyor happy (kubawerlos) -* minor #3516 Use null|type instead of ?type in PHPDocs (ntzm) +* minor #3516 Use `null|type` instead of `?type` in PHPDocs (ntzm) * minor #3518 FixerFactoryTest - Test each priority test file is listed as test (SpacePossum) * minor #3519 Fix typo (SpacePossum) * minor #3520 Fix typos: ran vs. run (SpacePossum) @@ -3190,7 +3620,7 @@ Changelog for v2.8.1 * bug #3199 TokensAnalyzer - getClassyElements (SpacePossum) * bug #3208 BracesFixer - Fix for instantiation in control structures (julienfalque, SpacePossum) -* bug #3215 BinaryOperatorSpacesFixer - Fix spaces around multiple exception catching (|) (ntzm) +* bug #3215 BinaryOperatorSpacesFixer - Fix spaces around multiple exception catching (ntzm) * bug #3216 AbstractLinesBeforeNamespaceFixer - add min. and max. option, not only single target count (SpacePossum) * bug #3217 TokenizerLinter - fix lack of linting when code is cached (SpacePossum, keradus) * minor #3200 Skip slow test when Xdebug is loaded (julienfalque) @@ -3237,7 +3667,7 @@ Changelog for v2.7.4 * bug #3199 TokensAnalyzer - getClassyElements (SpacePossum) * bug #3208 BracesFixer - Fix for instantiation in control structures (julienfalque, SpacePossum) -* bug #3215 BinaryOperatorSpacesFixer - Fix spaces around multiple exception catching (|) (ntzm) +* bug #3215 BinaryOperatorSpacesFixer - Fix spaces around multiple exception catching (ntzm) * bug #3216 AbstractLinesBeforeNamespaceFixer - add min. and max. option, not only single target count (SpacePossum) * bug #3217 TokenizerLinter - fix lack of linting when code is cached (SpacePossum, keradus) * minor #3200 Skip slow test when Xdebug is loaded (julienfalque) @@ -3259,7 +3689,7 @@ Changelog for v2.7.2 * bug #3062 BraceClassInstantiationTransformer - Fix instantiation inside method call braces case (julienfalque, keradus) * bug #3083 SingleBlankLineBeforeNamespaceFixer - Fix handling namespace right after opening tag (mlocati) * bug #3109 SwitchCaseSemicolonToColonFixer - Fix bug with nested constructs (SpacePossum) -* bug #3117 Multibyte character in array key makes alignment incorect (kubawerlos) +* bug #3117 Multibyte character in array key makes alignment incorrect (kubawerlos) * bug #3123 Cache - File permissions (SpacePossum) * bug #3138 NoHomoglyphNamesFixer - fix crash on non-ascii but not mapped either (SpacePossum) * bug #3172 IndentationTypeFixer - do not touch whitespace that is not indentation (SpacePossum) @@ -3459,7 +3889,7 @@ Changelog for v2.3.3 * bug #2807 NoUselessElseFixer - Fix detection of conditional block (SpacePossum) * bug #2809 Phar release - fix readme generation (SpacePossum, keradus) * bug #2827 MethodArgumentSpaceFixer - Always remove trailing spaces (julienfalque) -* bug #2835 SelfAcessorFixer - class property fix (mnabialek) +* bug #2835 SelfAccessorFixer - class property fix (mnabialek) * bug #2848 PhpdocIndentFixer - fix edge case with inline phpdoc (keradus) * bug #2849 BracesFixer - Fix indentation issues with comments (julienfalque) * bug #2851 Tokens - ensureWhitespaceAtIndex (GrahamCampbell, SpacePossum) @@ -3648,7 +4078,7 @@ Changelog for v2.2.17 * minor #3435 Add tests for general_phpdoc_annotation_remove (BackEndTea) * minor #3484 Create Tokens::findBlockStart (ntzm) * minor #3512 Add missing array typehints (ntzm) -* minor #3516 Use null|type instead of ?type in PHPDocs (ntzm) +* minor #3516 Use `null|type` instead of `?type` in PHPDocs (ntzm) * minor #3518 FixerFactoryTest - Test each priority test file is listed as test (SpacePossum) * minor #3520 Fix typos: ran vs. run (SpacePossum) * minor #3521 Use HTTPS (carusogabriel) @@ -3741,7 +4171,7 @@ Changelog for v2.2.10 * bug #3199 TokensAnalyzer - getClassyElements (SpacePossum) * bug #3208 BracesFixer - Fix for instantiation in control structures (julienfalque, SpacePossum) -* bug #3215 BinaryOperatorSpacesFixer - Fix spaces around multiple exception catching (|) (ntzm) +* bug #3215 BinaryOperatorSpacesFixer - Fix spaces around multiple exception catching (ntzm) * bug #3216 AbstractLinesBeforeNamespaceFixer - add min. and max. option, not only single target count (SpacePossum) * bug #3217 TokenizerLinter - fix lack of linting when code is cached (SpacePossum, keradus) * minor #3200 Skip slow test when Xdebug is loaded (julienfalque) @@ -3847,7 +4277,7 @@ Changelog for v2.2.5 * bug #2807 NoUselessElseFixer - Fix detection of conditional block (SpacePossum) * bug #2809 Phar release - fix readme generation (SpacePossum, keradus) * bug #2827 MethodArgumentSpaceFixer - Always remove trailing spaces (julienfalque) -* bug #2835 SelfAcessorFixer - class property fix (mnabialek) +* bug #2835 SelfAccessorFixer - class property fix (mnabialek) * bug #2848 PhpdocIndentFixer - fix edge case with inline phpdoc (keradus) * bug #2849 BracesFixer - Fix indentation issues with comments (julienfalque) * bug #2851 Tokens - ensureWhitespaceAtIndex (GrahamCampbell, SpacePossum) @@ -3936,7 +4366,9 @@ Changelog for v2.2.2 -------------------- Warning, this release breaks BC due to introduction of: + * minor #2554 Add short diff. output format (SpacePossum, keradus) + That PR was reverted in v2.2.3, which should be used instead of v2.2.2. * bug #2545 RuleSet - change resolvement (SpacePossum) @@ -4135,7 +4567,7 @@ Changelog for v2.0.1 * minor #2499 FileSpecificCodeSample - Specify class name relative to root namespace (localheinz, keradus) * minor #2506 SCA (SpacePossum) * minor #2515 Fix code indentation (keradus) -* minor #2521 SCA trailing spces check - ouput lines with trailing white space (SpacePossum) +* minor #2521 SCA trailing spces check - output lines with trailing white space (SpacePossum) * minor #2522 Fix docs and small code issues (keradus) Changelog for v2.0.0 @@ -4186,7 +4618,7 @@ Changelog for v2.0.0 * feature #1628 Added OrderedClassElementsFixer (gharlan) * feature #1742 path argument is used to create an intersection with existing finder (keradus, gharlan) * feature #1779 Added GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocAnnotationRenameFixer (keradus) -* feature #1811 Added NoSpacesInsideOfssetFixer (phansys) +* feature #1811 Added NoSpacesInsideOffsetFixer (phansys) * feature #1819 Added DirConstantFixer, ModernizeTypesCastingFixer, RandomApiMigrationFixer (kalessil, SpacePossum, keradus) * feature #1825 Added junit format (ekho) * feature #1862 FixerFactory - Do not allow conflicting fixers (SpacePossum) @@ -4303,7 +4735,7 @@ Changelog for v2.0.0 * minor #1846 FileFilterIterator - Corrected an iterator typehint (GrahamCampbell) * minor #1848 DocBlock - Remove some old unused phpdoc tags (GrahamCampbell) * minor #1856 NoDuplicateSemicolonsFixer - Remove overcomplete fixer (SpacePossum) -* minor #1861 Fix: Ofsset should be Offset (localheinz) +* minor #1861 Fix: Offset should be Offset (localheinz) * minor #1867 Print non-report output to stdErr (SpacePossum, keradus) * minor #1873 Enhancement: Show path to cache file if it exists (localheinz) * minor #1875 renamed Composer package (fabpot) @@ -4366,7 +4798,7 @@ Changelog for v2.0.0 * minor #2318 *TestCase - Reduce visibility of setUp() (localheinz) * minor #2319 Code grooming (keradus) * minor #2322 DX: use whitemessy aware assertion (keradus) -* minor #2324 Echo|Print*Fixer - unify printing fixers (SpacePossum, keradus) +* minor #2324 `Echo|Print*Fixer` - unify printing fixers (SpacePossum, keradus) * minor #2337 Normalize rule naming (keradus) * minor #2338 Drop hacks for unsupported HHVM (keradus) * minor #2339 Add some Fixer descriptions (SpacePossum, keradus) @@ -4444,7 +4876,7 @@ Changelog for v1.12.3 * bug #2209 LinefeedFixer - Fix in a safe way (SpacePossum) * bug #2228 NoEmptyLinesAfterPhpdocs, SingleBlankLineBeforeNamespace - Fix priority (SpacePossum) * bug #2230 FunctionDeclarationFixer - Fix T_USE case (SpacePossum) -* bug #2232 Add a test for style of varaible decalration : var (daiglej) +* bug #2232 Add a test for style of variable declaration : var (daiglej) * bug #2246 Fix itest requirements (keradus) * minor #2238 .gitattributes - specified line endings (keradus) * minor #2239 IntegrationCase - no longer internal (keradus) @@ -4733,7 +5165,7 @@ Changelog for v1.10.1 * bug #1444 OrderedUseFixer - fix next case (keradus) * bug #1441 BracesFixer - fix next case (keradus) * bug #1422 AlignDoubleArrowFixer - fix handling of nested array (SpacePossum) -* bug #1425 PhpdocInlineTagFixerTest - fix case when met inalid PHPDoc (keradus) +* bug #1425 PhpdocInlineTagFixerTest - fix case when met invalid PHPDoc (keradus) * bug #1419 AlignDoubleArrowFixer, AlignEqualsFixer - fix priorities (keradus) * bug #1415 BlanklineAfterOpenTagFixer - Do not add a line break if there is one already. (SpacePossum) * bug #1410 PhpdocIndentFixer - Fix for open tag (SpacePossum) @@ -4881,7 +5313,7 @@ Changelog for v1.5.1 -------------------- * bug #1054 VisibilityFixer - fix var with array value assigned (localheinz, keradus) -* bug #1048 MultilineArrayTrailingCommaFixer, SingleArrayNoTrailingCommaFixer - using heredoc inside array not cousing to treat it as multiline array (keradus) +* bug #1048 MultilineArrayTrailingCommaFixer, SingleArrayNoTrailingCommaFixer - using heredoc inside array not causing to treat it as multiline array (keradus) * bug #1043 PhpdocToCommentFixer - also check other control structures, besides foreach (ceeram) * bug #1045 OrderedUseFixer - fix namespace order for trailing digits (rusitschka) * bug #1035 PhpdocToCommentFixer - Add static as valid keyword for structural element (ceeram) @@ -4915,7 +5347,7 @@ Changelog for v1.5 * minor #957 Fix Fixers methods order (GrahamCampbell) * minor #944 Enable caching of composer downloads on Travis (stof) * minor #941 EncodingFixer - enhance tests (keradus) -* minor #938 Psr0Fixer - remove unneded assignment (keradus) +* minor #938 Psr0Fixer - remove unneeded assignment (keradus) * minor #936 FixerTest - test description consistency (keradus) * minor #933 NoEmptyLinesAfterPhpdocsFixer - remove unneeded code, clarify description (ceeram) * minor #934 StdinFileInfo::getFilename - Replace phpdoc with normal comment and add back empty line before return (ceeram) @@ -4958,7 +5390,7 @@ Changelog for v1.4 * bug #945 Skip files containing __halt_compiler() on PHP 5.3 (stof) * bug #946 BracesFixer - fix typo in exception name (keradus) * bug #940 Tokens::setCode - apply missing transformation (keradus) -* bug #908 BracesFixer - fix invalide inserting brace for control structure without brace and lambda inside of it (keradus) +* bug #908 BracesFixer - fix invalid inserting brace for control structure without brace and lambda inside of it (keradus) * bug #903 NoEmptyLinesAfterPhpdocsFixer - fix bug with Windows style lines (GrahamCampbell) * bug #895 [PSR-2] Preserve blank line after control structure opening brace (marcaube) * bug #892 Fixed the double arrow multiline whitespace fixer (GrahamCampbell) @@ -5022,7 +5454,7 @@ Changelog for v1.2 * minor #779 Fixed a docblock type (GrahamCampbell) * minor #765 Typehinting in FileCacheManager, remove unused variable in Tokens (keradus) * minor #764 SelfUpdateCommand - get local version only if remote version was successfully obtained (keradus) -* minor #761 aling => (keradus) +* minor #761 align => (keradus) * minor #757 Some minor code simplify and extra test (keradus) * minor #713 Download php-cs-fixer.phar without sudo (michaelsauter) * minor #742 Various Minor Improvements (GrahamCampbell) diff --git a/vendor/friendsofphp/php-cs-fixer/CONTRIBUTING.md b/vendor/friendsofphp/php-cs-fixer/CONTRIBUTING.md index 8dc5ba17..f0f5a429 100644 --- a/vendor/friendsofphp/php-cs-fixer/CONTRIBUTING.md +++ b/vendor/friendsofphp/php-cs-fixer/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributions Are Welcome! -If you need any help, don't hesitate to ask the community using [GitHub Discussions](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/discussions/categories/q-a) or [Gitter](https://gitter.im/PHP-CS-Fixer/Lobby). +If you need any help, don't hesitate to ask the community using [GitHub Discussions](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/discussions/categories/q-a). ## Glossary @@ -18,7 +18,10 @@ A *config* knows about the code style rules and the files and directories that m ## How to contribute -ℹ️ **IMPORTANT**: before contributing with really significant changes that require a lot of effort or are crucial from this tool's architecture perspective, please open [RFC on GitHub Discussion](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/discussions/categories/rfc). The development effort should start only after the proposal is discussed and the approach aligned. +> [!IMPORTANT] +> Before contributing with _really_ significant changes that require a lot of effort or are crucial from this tool's +> architecture perspective, please open [RFC on GitHub Discussion](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/discussions/categories/rfc). +> The development effort should start only after the proposal is discussed and the approach aligned. ### Development @@ -26,9 +29,9 @@ A *config* knows about the code style rules and the files and directories that m * Create new branch on top of the latest revision of `master` branch (if you already had project locally, then make sure to update this branch before going to next steps). It's good when branch's name reflects intent of the changes, but this is not strict requirement since pull request provides description of the change. However, with good branch naming it's easier to work on multiple changes simultaneously. * Install dependencies by running `composer update` (since project does not contain `composer.lock` it's better to ensure latest versions of packages by running `update` command instead of `install`). * Make changes. Please remember that **all** changes have to be covered by tests. - * if you work on a bug fix, please start with reproducing the problem by adding failing test case(s). When you have failing test case(s), you can [create pull request](#opening-a-pull-request) just to reproduce fail in the CI. Then you can provide fix _in the subsequent commits_, it will make code review easier. It's allowed to modify existing test cases in bug fix pull request, but *only if* current behavior is proved to be invalid. - * if you work on existing fixers then don't change existing test cases, because these are contract between the maintainers and users (they ensure how tool works). Add new test cases that cover provided changes - preferred way of defining test cases is with [data provider](https://docs.phpunit.de/en/10.0/writing-tests-for-phpunit.html#data-providers) which uses `yield` with proper case description as a key (e.g. `yield 'Some specific scenario' => ['some', 'example', 'data'];`). Codebase may still contain test cases in different format, and it's totally acceptable to use `yield` approach next to existing `return` usages. -* Update documentation: `composer docs`. This requires the highest version of PHP supported by PHP CS Fixer. If it is not installed on your system, you can run it in a Docker container instead: `docker-compose run php-8.2 php dev-tools/doc.php`. + * if you work on a bug fix, please start with reproducing the problem by adding failing test case(s). When you have failing test case(s), you can [create pull request](#opening-a-pull-request) just to reproduce fail in the CI. Then you can provide fix _in the subsequent commits_, it will make code review easier. It's allowed to modify existing test cases in bug fix pull request, but *only if* current behavior is proved to be invalid. + * if you work on existing fixers then don't change existing test cases, because these are contract between the maintainers and users (they ensure how tool works). Add new test cases that cover provided changes - preferred way of defining test cases is with [data provider](https://docs.phpunit.de/en/10.0/writing-tests-for-phpunit.html#data-providers) which uses `yield` with proper case description as a key (e.g. `yield 'Some specific scenario' => ['some', 'example', 'data'];`). Codebase may still contain test cases in different format, and it's totally acceptable to use `yield` approach next to existing `return` usages. +* Update documentation: `composer docs`. This requires the highest version of PHP supported by PHP CS Fixer. If it is not installed on your system, you can run it in a Docker container instead: `docker compose run php-8.2 php dev-tools/doc.php`. * Run QA suite: `composer qa`. * Fix project itself (if needed): `composer cs:fix`. @@ -37,43 +40,50 @@ A *config* knows about the code style rules and the files and directories that m You can do some things to increase the chance that your pull request is accepted without communication ping-pong between you and the reviewers: * Submit [single](https://en.wikipedia.org/wiki/Single-responsibility_principle) pull request per fix or feature. -* Don't amend commits because it makes review rounds harder - all commits from your branch will be squashed (without commit messages) during merge, so you can treat pull request as a playground, without keeping everything tidy at any point. -* If your changes are not up-to-date, [rebase](https://git-scm.com/docs/git-rebase) your branch onto the parent branch. Do it regularly whenever your branch is behind `master` branch, that will eliminate risk of problems after the merge. +* Keep meaningful commit logs, don't use meaningless messages (e.g. `foo`, `more work`, `more work`, `more work`) and don't push complex PR as a single commit. +* Don't [amend](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---amend) commits because it makes review rounds harder - all commits from your branch will be squashed (without commit messages) during the merge. * Follow the conventions used in the project. * Remember about tests and documentation. * Don't bump `PhpCsFixer\Console\Application::VERSION`, it's done during release. +> [!IMPORTANT] +> Your pull request will have much higher chance of getting merged if you allow maintainers to push changes to your +> branch. You can do it by ticking "Allow edits and access to secrets by maintainers" checkbox, but please keep in mind +> this option is available only if your PR is created from a user's fork. If your fork is a part of organisation, then +> you can add [Fixer maintainers](https://github.com/orgs/PHP-CS-Fixer/people) as members of that repository. This way +> maintainers will be able to provide required changes or rebase your branch (only up-to-date PRs can be merged). + ## Working With Docker This project provides a Docker setup that allows working on it using any of the PHP versions supported by the tool. To use it, you first need to install [Docker](https://docs.docker.com/get-docker/) ([Docker Compose](https://docs.docker.com/compose/) is a built-in plugin of the main tool). -Next, copy [`docker-compose.override.yaml.dist`](./docker-compose.override.yaml.dist) to `docker-compose.override.yaml` and edit it to your needs. The relevant parameters that might require some tweaking have comments to help you. +Next, copy [`compose.override.dist.yaml`](./compose.override.dist.yaml) to `compose.override.yaml` and edit it to your needs. The relevant parameters that might require some tweaking have comments to help you. You can then build the images: ```console -docker-compose build --parallel +docker compose build --parallel ``` -Now you can run commands needed to work on the project. For example, say you want to run PHPUnit tests on PHP 7.4: +Now you can run commands needed to work on the project. For example, say you want to run PHPUnit tests on PHP 8.2: ```console -docker-compose run php-7.4 vendor/bin/phpunit +docker compose run php-8.2 vendor/bin/phpunit ``` Sometimes it can be more convenient to have a shell inside the container: ```console -docker-compose run php-7.4 sh -/app vendor/bin/phpunit +docker compose run php-7.4 sh +/fixer vendor/bin/phpunit ``` The images come with an [`xdebug` script](github.com/julienfalque/xdebug/) that allows running any PHP command with Xdebug enabled to help debug problems. ```console -docker-compose run php-7.4 xdebug vendor/bin/phpunit +docker compose run php-8.2 xdebug vendor/bin/phpunit ``` If you're using PhpStorm, you need to create a [server](https://www.jetbrains.com/help/phpstorm/servers.html) with a name that matches the `PHP_IDE_CONFIG` environment variable defined in the Docker Compose configuration files, which is `php-cs-fixer` by default. diff --git a/vendor/friendsofphp/php-cs-fixer/README.md b/vendor/friendsofphp/php-cs-fixer/README.md index fb7f6a78..c5e0ac30 100644 --- a/vendor/friendsofphp/php-cs-fixer/README.md +++ b/vendor/friendsofphp/php-cs-fixer/README.md @@ -4,8 +4,7 @@

-PHP Coding Standards Fixer -========================== +# PHP Coding Standards Fixer The PHP Coding Standards Fixer (PHP CS Fixer) tool fixes your code to follow standards; whether you want to follow PHP coding standards as defined in the PSR-1, PSR-2, etc., @@ -22,9 +21,10 @@ projects. This tool does not only detect them, but also fixes them for you. ## Supported PHP Versions * PHP 7.4 -* PHP 8.0 (except PHP 8.0.0 due to [bug in PHP tokenizer](https://bugs.php.net/bug.php?id=80462)) +* PHP 8.0 * PHP 8.1 * PHP 8.2 +* PHP 8.3 > **Note** > Each new PHP version requires a huge effort to support the new syntax. @@ -48,6 +48,7 @@ composer require --working-dir=tools/php-cs-fixer friendsofphp/php-cs-fixer ``` Or using the main `composer.json`: + ```console composer require --dev friendsofphp/php-cs-fixer ``` @@ -55,10 +56,24 @@ composer require --dev friendsofphp/php-cs-fixer For more details and other installation methods, see [installation instructions](./doc/installation.rst). +### Run with Docker + +You can use pre-built Docker images to run ``php-cs-fixer``. + +```console +docker run -v $(pwd):/code ghcr.io/php-cs-fixer/php-cs-fixer:${FIXER_VERSION:-3-php8.3} fix src +``` + +`$FIXER_VERSION` used in example above is an identifier of a release you want to use, which is based on Fixer and PHP versions combined. There are different tags for each Fixer's SemVer level and PHP version with syntax `-php`. For example: + +* `3.47.0-php7.4` +* `3.47-php8.0` +* `3-php8.3` + ### Usage Assuming you installed PHP CS Fixer as instructed above, you can run the -following command to fix the files PHP files in the `src` directory: +following command to fix the PHP files in the `src` directory: ```console tools/php-cs-fixer/vendor/bin/php-cs-fixer fix src @@ -82,11 +97,11 @@ Dedicated plugins exist for: ## Community -The PHP CS Fixer is maintained on GitHub at https://github.com/PHP-CS-Fixer/PHP-CS-Fixer. +The PHP CS Fixer is maintained on GitHub at . Bug reports and ideas about new features are welcome there. -You can reach us at https://gitter.im/PHP-CS-Fixer/Lobby about the project, -configuration, possible improvements, ideas and questions, please visit us! +You can reach us in the [GitHub Discussions](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/discussions/) regarding the +project, configuration, possible improvements, ideas and questions. Please visit us there! ## Contribute diff --git a/vendor/friendsofphp/php-cs-fixer/UPGRADE-v3.md b/vendor/friendsofphp/php-cs-fixer/UPGRADE-v3.md index 00e0a9c5..bea1ff4f 100644 --- a/vendor/friendsofphp/php-cs-fixer/UPGRADE-v3.md +++ b/vendor/friendsofphp/php-cs-fixer/UPGRADE-v3.md @@ -1,21 +1,18 @@ -UPGRADE GUIDE FROM 2.x to 3.0 -============================= +# UPGRADE GUIDE FROM 2.x to 3.0 This is guide for upgrade from version 2.x to 3.0 for using the CLI tool. *Before following this guide, install [v2.19](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/tag/v2.19.0) and run in verbose mode (`php-cs-fixer fix -v`) or in future mode (`PHP_CS_FIXER_FUTURE_MODE=1 php-cs-fixer fix`) to identify deprecations and fix them first.* -Rename of files ---------------- +## Rename of files | 2.x | 3.0 | Description | -| ---------------- | ------------------------ | -------------------------------------- | +|------------------|--------------------------|----------------------------------------| | `.php_cs` | `.php-cs-fixer.php` | Configuration file (local) | | `.php_cs.dist` | `.php-cs-fixer.dist.php` | Configuration file (to be distributed) | | `.php_cs.cache` | `.php-cs-fixer.cache` | Cache file | -CLI options ------------ +## CLI options | 2.x | 3.0 | Description | Note | | ---------------- | --------------- | ----------------------------------------------- | -------------------------------------- | @@ -27,94 +24,93 @@ CLI options | --rules | --rules | Default value changed from @PSR2 to @PSR12 | | | --config --rules | | | No longer allowed to pass both | -Changes to rules ----------------- +## Changes to rules ### Renamed rules -Old name | New name | Note --------- | -------- | ---- -`blank_line_before_return` | `blank_line_before_statement` | use configuration `['statements' => ['return']]` -`final_static_access` | `self_static_accessor` | -`hash_to_slash_comment` | `single_line_comment_style` | use configuration `['comment_types' => ['hash']]` -`lowercase_constants` | `constant_case` | use configuration `['case' => 'lower']` -`method_separation` | `class_attributes_separation` | use configuration `['elements' => ['method']]` -`no_extra_consecutive_blank_lines` | `no_extra_blank_lines` | -`no_multiline_whitespace_before_semicolons` | `multiline_whitespace_before_semicolons` | -`no_short_echo_tag` | `echo_tag_syntax` | use configuration `['format' => 'long']` -`php_unit_ordered_covers` | `phpdoc_order_by_value` | use configuration `['annotations' => [ 'covers' ]]` -`phpdoc_inline_tag` | `general_phpdoc_tag_rename`, `phpdoc_inline_tag_normalizer` and `phpdoc_tag_type` | -`pre_increment` | `increment_style` | use configuration `['style' => 'pre']` -`psr0` | `psr_autoloading` | use configuration `['dir' => x ]` -`psr4` | `psr_autoloading` | -`silenced_deprecation_error` | `error_suppression` | -`trailing_comma_in_multiline_array` | `trailing_comma_in_multiline` | use configuration `['elements' => ['arrays']]` +| Old name | New name | Note | +|--------------------------------------------|-----------------------------------------------------------------------------------|------------------------------------------------------| +|`blank_line_before_return` | `blank_line_before_statement` | use configuration `['statements' => ['return']]` | +|`final_static_access` | `self_static_accessor` | | +|`hash_to_slash_comment` | `single_line_comment_style` | use configuration `['comment_types' => ['hash']]` | +|`lowercase_constants` | `constant_case` | use configuration `['case' => 'lower']` | +|`method_separation` | `class_attributes_separation` | use configuration `['elements' => ['method']]` | +|`no_extra_consecutive_blank_lines` | `no_extra_blank_lines` | | +|`no_multiline_whitespace_before_semicolons` | `multiline_whitespace_before_semicolons` | | +|`no_short_echo_tag` | `echo_tag_syntax` | use configuration `['format' => 'long']` | +|`php_unit_ordered_covers` | `phpdoc_order_by_value` | use configuration `['annotations' => [ 'covers' ]]` | +|`phpdoc_inline_tag` | `general_phpdoc_tag_rename`, `phpdoc_inline_tag_normalizer` and `phpdoc_tag_type` | | +|`pre_increment` | `increment_style` | use configuration `['style' => 'pre']` | +|`psr0` | `psr_autoloading` | use configuration `['dir' => x ]` | +|`psr4` | `psr_autoloading` | | +|`silenced_deprecation_error` | `error_suppression` | | +|`trailing_comma_in_multiline_array` | `trailing_comma_in_multiline` | use configuration `['elements' => ['arrays']]` | ### Removed rootless configuration -Rule | Root option | Note ------------------------------------- | -------------- | ---- -`general_phpdoc_annotation_remove` | `annotations` -`no_extra_consecutive_blank_lines` | `tokens` -`no_spaces_around_offset` | `positions` -`no_unneeded_control_parentheses` | `statements` -`ordered_class_elements` | `order` -`php_unit_construct` | `assertions` -`php_unit_dedicate_assert` | `target` | root option works differently than rootless configuration -`php_unit_strict` | `assertions` -`phpdoc_no_alias_tag` | `replacements` -`phpdoc_return_self_reference` | `replacements` -`random_api_migration` | `replacements` -`single_class_element_per_statement` | `elements` -`visibility_required` | `elements` +| Rule | Root option | Note | +|--------------------------------------| -------------- |-----------------------------------------------------------| +| `general_phpdoc_annotation_remove` | `annotations` | | +| `no_extra_consecutive_blank_lines` | `tokens` | | +| `no_spaces_around_offset` | `positions` | | +| `no_unneeded_control_parentheses` | `statements` | | +| `ordered_class_elements` | `order` | | +| `php_unit_construct` | `assertions` | | +| `php_unit_dedicate_assert` | `target` | root option works differently than rootless configuration | +| `php_unit_strict` | `assertions` | | +| `phpdoc_no_alias_tag` | `replacements` | | +| `phpdoc_return_self_reference` | `replacements` | | +| `random_api_migration` | `replacements` | | +| `single_class_element_per_statement` | `elements` | | +| `visibility_required` | `elements` | | ### Changed options -Rule | Option | Change ----- | ------ | ------ -`binary_operator_spaces` | `align_double_arrow` | option was removed, use `operators` instead -`binary_operator_spaces` | `align_equals` | option was removed use `operators` instead -`blank_line_before_statement` | `statements: die` | option `die` was removed from `statements`, use `exit` instead -`class_attributes_separation` | `elements` | option does no longer accept flat array as a value, use map instead -`class_definition` | `multiLineExtendsEachSingleLine` | option was renamed to `multi_line_extends_each_single_line` -`class_definition` | `singleItemSingleLine` | option was renamed to `single_item_single_line` -`class_definition` | `singleLine` | option was renamed to `single_line` -`doctrine_annotation_spaces` | `around_argument_assignments` | option was removed, use `before_argument_assignments` and `after_argument_assignments` instead -`doctrine_annotation_spaces` | `around_array_assignments` | option was removed, use `after_array_assignments_colon`, `after_array_assignments_equals`, `before_array_assignments_colon` and `before_array_assignments_equals` instead -`final_internal_class` | `annotation-black-list` | option was renamed, use `annotation_exclude` -`final_internal_class` | `annotation-white-list` | option was renamed, use `annotation_include` -`final_internal_class` | `consider-absent-docblock-as-internal-class` | option was renamed, use `consider_absent_docblock_as_internal_class` -`header_comment` | `commentType` | option was renamed to `comment_type` -`is_null` | `use_yoda_style` | option was removed, use `yoda_style` rule instead -`no_extra_consecutive_blank_lines` | `tokens` | one of possible values, `useTrait`, was renamed to `use_trait` -`ordered_class_elements` | `sortAlgorithm` | option was renamed, use `sort_algorithm` instead -`ordered_imports` | `importsOrder` | option was renamed, use `imports_order` -`ordered_imports` | `sortAlgorithm` | option was renamed, use `sort_algorithm` -`php_unit_dedicate_assert` | `functions` | option was removed, use `target` instead -`php_unit_test_annotation` | `case` | option was removed, use `php_unit_method_casing` rule instead +| Rule | Option | Change | +|------------------------------------|----------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `binary_operator_spaces` | `align_double_arrow` | option was removed, use `operators` instead | +| `binary_operator_spaces` | `align_equals` | option was removed use `operators` instead | +| `blank_line_before_statement` | `statements: die` | option `die` was removed from `statements`, use `exit` instead | +| `class_attributes_separation` | `elements` | option does no longer accept flat array as a value, use map instead | +| `class_definition` | `multiLineExtendsEachSingleLine` | option was renamed to `multi_line_extends_each_single_line` | +| `class_definition` | `singleItemSingleLine` | option was renamed to `single_item_single_line` | +| `class_definition` | `singleLine` | option was renamed to `single_line` | +| `doctrine_annotation_spaces` | `around_argument_assignments` | option was removed, use `before_argument_assignments` and `after_argument_assignments` instead | +| `doctrine_annotation_spaces` | `around_array_assignments` | option was removed, use `after_array_assignments_colon`, `after_array_assignments_equals`, `before_array_assignments_colon` and `before_array_assignments_equals` instead | +| `final_internal_class` | `annotation-black-list` | option was renamed, use `annotation_exclude` | +| `final_internal_class` | `annotation-white-list` | option was renamed, use `annotation_include` | +| `final_internal_class` | `consider-absent-docblock-as-internal-class` | option was renamed, use `consider_absent_docblock_as_internal_class` | +| `header_comment` | `commentType` | option was renamed to `comment_type` | +| `is_null` | `use_yoda_style` | option was removed, use `yoda_style` rule instead | +| `no_extra_consecutive_blank_lines` | `tokens` | one of possible values, `useTrait`, was renamed to `use_trait` | +| `ordered_class_elements` | `sortAlgorithm` | option was renamed, use `sort_algorithm` instead | +| `ordered_imports` | `importsOrder` | option was renamed, use `imports_order` | +| `ordered_imports` | `sortAlgorithm` | option was renamed, use `sort_algorithm` | +| `php_unit_dedicate_assert` | `functions` | option was removed, use `target` instead | +| `php_unit_test_annotation` | `case` | option was removed, use `php_unit_method_casing` rule instead | ### Changed default values of options -Rule | Option | Old value | New value ----- | ---- | ---- | ---- -`array_syntax` | `syntax` | `'long'` | `'short'` -`function_to_constant` | `functions` | `['get_class', 'php_sapi_name', 'phpversion', 'pi']` | `['get_called_class', 'get_class', 'php_sapi_name', 'phpversion', 'pi']` -`list_syntax` | `syntax` | `'long'` | `'short'` -`method_argument_space` | `on_multiline` | `'ignore'` | `'ensure_fully_multiline'` -`native_constant_invocation` | `strict` | `false` | `true` -`native_function_casing` | `include` | `'@internal'` | `'@compiler_optimized'` -`native_function_invocation` | `include` | `'@internal'` | `'@compiler_optimized'` -`native_function_invocation` | `strict` | `false` | `true` -`non_printable_character` | `use_escape_sequences_in_strings` | `false` | `true` (when running on PHP 7.0 and up) -`php_unit_dedicate_assert` | `target` | `'5.0'` | `'newest'` -`phpdoc_align` | `tags` | `['param', 'return', 'throws', 'type', 'var']` | `['method', 'param', 'property', 'return', 'throws', 'type', 'var']` -`phpdoc_scalar` | `types` | `['boolean', 'double', 'integer', 'real', 'str']` | `['boolean', 'callback', 'double', 'integer', 'real', 'str']` +| Rule | Option | Old value | New value | +|------------------------------|-----------------------------------|------------------------------------------------------|--------------------------------------------------------------------------| +| `array_syntax` | `syntax` | `'long'` | `'short'` | +| `function_to_constant` | `functions` | `['get_class', 'php_sapi_name', 'phpversion', 'pi']` | `['get_called_class', 'get_class', 'php_sapi_name', 'phpversion', 'pi']` | +| `list_syntax` | `syntax` | `'long'` | `'short'` | +| `method_argument_space` | `on_multiline` | `'ignore'` | `'ensure_fully_multiline'` | +| `native_constant_invocation` | `strict` | `false` | `true` | +| `native_function_casing` | `include` | `'@internal'` | `'@compiler_optimized'` | +| `native_function_invocation` | `include` | `'@internal'` | `'@compiler_optimized'` | +| `native_function_invocation` | `strict` | `false` | `true` | +| `non_printable_character` | `use_escape_sequences_in_strings` | `false` | `true` (when running on PHP 7.0 and up) | +| `php_unit_dedicate_assert` | `target` | `'5.0'` | `'newest'` | +| `phpdoc_align` | `tags` | `['param', 'return', 'throws', 'type', 'var']` | `['method', 'param', 'property', 'return', 'throws', 'type', 'var']` | +| `phpdoc_scalar` | `types` | `['boolean', 'double', 'integer', 'real', 'str']` | `['boolean', 'callback', 'double', 'integer', 'real', 'str']` | ### Removed rule sets -Rule set | Note --------- | ---- -`@PHP56Migration` | was empty +| Rule set | Note | +|-------------------|------------| +| `@PHP56Migration` | was empty | ### Rule behavior changes @@ -124,8 +120,7 @@ Rule set | Note - `udiff` output now includes the file name in the output (if applicable) -Code BC changes -=============== +## Code BC changes ### Removed; various @@ -138,11 +133,11 @@ Code BC changes - `MethodArgumentSpaceFixer` deprecated methods have been removed - `NoMixedEchoPrintFixer` the property `$defaultConfig` has been removed - class `Tokens`, the following methods has been removed: - - `current()` - - `key()` - - `next()` - - `rewind()` - - `valid()` + - `current()` + - `key()` + - `next()` + - `rewind()` + - `valid()` - namespace `PhpCsFixer\Test\` and each class in it has been removed, as it served pure development purpose and should not be part of production code - reach out to community if you are willing to help building dev package ### Interface changes diff --git a/vendor/friendsofphp/php-cs-fixer/ci-integration.sh b/vendor/friendsofphp/php-cs-fixer/ci-integration.sh index 6ede4fd5..39d99955 100644 --- a/vendor/friendsofphp/php-cs-fixer/ci-integration.sh +++ b/vendor/friendsofphp/php-cs-fixer/ci-integration.sh @@ -5,4 +5,4 @@ IFS=' ' CHANGED_FILES=$(git diff --name-only --diff-filter=ACMRTUXB "${COMMIT_RANGE}") if ! echo "${CHANGED_FILES}" | grep -qE "^(\\.php-cs-fixer(\\.dist)?\\.php|composer\\.lock)$"; then EXTRA_ARGS=$(printf -- '--path-mode=intersection\n--\n%s' "${CHANGED_FILES}"); else EXTRA_ARGS=''; fi -vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php -v --stop-on-violation --using-cache=no ${EXTRA_ARGS} +vendor/bin/php-cs-fixer check --config=.php-cs-fixer.dist.php -v --show-progress=dots --stop-on-violation --using-cache=no ${EXTRA_ARGS} diff --git a/vendor/friendsofphp/php-cs-fixer/composer.json b/vendor/friendsofphp/php-cs-fixer/composer.json index ec122c6e..0434e876 100644 --- a/vendor/friendsofphp/php-cs-fixer/composer.json +++ b/vendor/friendsofphp/php-cs-fixer/composer.json @@ -21,36 +21,36 @@ ], "require": { "php": "^7.4 || ^8.0", + "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", - "composer/semver": "^3.3", + "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", - "sebastian/diff": "^4.0 || ^5.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.27", - "symfony/polyfill-php80": "^1.27", - "symfony/polyfill-php81": "^1.27", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { "facile-it/paraunit": "^1.3 || ^2.0", + "infection/infection": "^0.27.11", "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.0", + "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.5.3", + "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.16", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "symfony/phpunit-bridge": "^6.2.3", - "symfony/yaml": "^5.4 || ^6.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -85,10 +85,11 @@ "Composer\\Config::disableProcessTimeout", "paraunit run --testsuite auto-review" ], - "cs:check": "@php php-cs-fixer check --diff", + "cs:check": "@php php-cs-fixer check --verbose --diff", "cs:fix": "@php php-cs-fixer fix", "cs:fix:parallel": "echo '🔍 Will run in batches of 50 files.'; if [[ -f .php-cs-fixer.php ]]; then FIXER_CONFIG=.php-cs-fixer.php; else FIXER_CONFIG=.php-cs-fixer.dist.php; fi; php php-cs-fixer list-files --config=$FIXER_CONFIG | xargs -n 50 -P 8 php php-cs-fixer fix --config=$FIXER_CONFIG --path-mode intersection 2> /dev/null", "docs": "@php dev-tools/doc.php", + "infection": "@test:mutation", "install-tools": "@composer --working-dir=dev-tools install", "mess-detector": "@php dev-tools/vendor/bin/phpmd . ansi dev-tools/mess-detector/phpmd.xml --exclude vendor/*,dev-tools/vendor/*,dev-tools/phpstan/*,tests/Fixtures/*", "normalize": [ @@ -111,6 +112,7 @@ "./dev-tools/check_file_permissions.sh", "./dev-tools/check_trailing_spaces.sh", "@normalize", + "@unused-deps", "@require-checker", "@auto-review" ], @@ -126,12 +128,20 @@ ], "test:coverage": [ "Composer\\Config::disableProcessTimeout", - "paraunit coverage --testsuite unit --exclude-group covers-nothing" + "@composer show facile-it/paraunit ^2 && (paraunit coverage --testsuite unit --pass-through=--exclude-group=covers-nothing) || (paraunit coverage --testsuite unit --exclude-group covers-nothing)" ], "test:integration": [ "Composer\\Config::disableProcessTimeout", "paraunit run --testsuite integration" ], + "test:mutation": [ + "Composer\\Config::disableProcessTimeout", + "infection --threads=max --only-covered --min-covered-msi=80" + ], + "test:short-open-tag": [ + "Composer\\Config::disableProcessTimeout", + "@php -d short_open_tag=1 ./vendor/bin/phpunit --do-not-cache-result --testsuite short-open-tag" + ], "test:smoke": [ "Composer\\Config::disableProcessTimeout", "paraunit run --testsuite smoke" @@ -139,7 +149,8 @@ "test:unit": [ "Composer\\Config::disableProcessTimeout", "paraunit run --testsuite unit" - ] + ], + "unused-deps": "@php dev-tools/vendor/bin/composer-unused --excludePackage=composer/xdebug-handler" }, "scripts-descriptions": { "auto-review": "Execute Auto-review", @@ -147,6 +158,7 @@ "cs:fix": "Fix coding standards", "cs:fix:parallel": "Fix coding standards in naive parallel mode (using xargs)", "docs": "Regenerate docs", + "infection": "Alias for 'test:mutation'", "install-tools": "Install DEV tools", "mess-detector": "Analyse code with Mess Detector", "normalize": "Run normalization for composer.json files", @@ -163,7 +175,10 @@ "test:all": "Run Unit and Integration tests (but *NOT* Smoke tests)", "test:coverage": "Run tests that provide code coverage", "test:integration": "Run Integration tests", + "test:mutation": "Run mutation tests", + "test:short-open-tag": "Run tests with \"short_open_tag\" enabled", "test:smoke": "Run Smoke tests", - "test:unit": "Run Unit tests" + "test:unit": "Run Unit tests", + "unused-deps": "Verifies if app has dependencies that are not used" } } diff --git a/vendor/friendsofphp/php-cs-fixer/logo.md b/vendor/friendsofphp/php-cs-fixer/logo.md index c2877f71..68e03a58 100644 --- a/vendor/friendsofphp/php-cs-fixer/logo.md +++ b/vendor/friendsofphp/php-cs-fixer/logo.md @@ -1,3 +1,3 @@ The logo is © 2010+ Sensio Labs. -Original resolution can be found at https://github.com/PHP-CS-Fixer/logo . +Original resolution can be found at . diff --git a/vendor/friendsofphp/php-cs-fixer/php-cs-fixer b/vendor/friendsofphp/php-cs-fixer/php-cs-fixer index e29468be..402b49ae 100755 --- a/vendor/friendsofphp/php-cs-fixer/php-cs-fixer +++ b/vendor/friendsofphp/php-cs-fixer/php-cs-fixer @@ -28,8 +28,8 @@ set_error_handler(static function ($severity, $message, $file, $line) { exit(1); } - if (\PHP_VERSION_ID < 70400 || \PHP_VERSION_ID >= 80300) { - fwrite(STDERR, "PHP needs to be a minimum version of PHP 7.4.0 and maximum version of PHP 8.2.*.\n"); + if (\PHP_VERSION_ID < 70400 || \PHP_VERSION_ID >= 80400) { + fwrite(STDERR, "PHP needs to be a minimum version of PHP 7.4.0 and maximum version of PHP 8.3.*.\n"); fwrite(STDERR, 'Current PHP version: '.PHP_VERSION.".\n"); if (getenv('PHP_CS_FIXER_IGNORE_ENV')) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/AbstractFunctionReferenceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/AbstractFunctionReferenceFixer.php index 97a92def..dfddeb51 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/AbstractFunctionReferenceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/AbstractFunctionReferenceFixer.php @@ -43,7 +43,7 @@ public function isRisky(): bool * Looks up Tokens sequence for suitable candidates and delivers boundaries information, * which can be supplied by other methods in this abstract class. * - * @return null|int[] returns $functionName, $openParenthesis, $closeParenthesis packed into array + * @return ?array{int, int, int} returns $functionName, $openParenthesis, $closeParenthesis packed into array */ protected function find(string $functionNameToSearch, Tokens $tokens, int $start = 0, ?int $end = null): ?array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/AbstractNoUselessElseFixer.php b/vendor/friendsofphp/php-cs-fixer/src/AbstractNoUselessElseFixer.php index 48cd7763..b45be5ac 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/AbstractNoUselessElseFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/AbstractNoUselessElseFixer.php @@ -93,7 +93,7 @@ protected function isSuperfluousElse(Tokens $tokens, int $index): bool * * @param int $index T_IF, T_ELSE, T_ELSEIF * - * @return int[] + * @return array{int, int} */ private function getPreviousBlock(Tokens $tokens, int $index): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocToTypeDeclarationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocToTypeDeclarationFixer.php index e9d70639..4e50a678 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocToTypeDeclarationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocToTypeDeclarationFixer.php @@ -29,10 +29,12 @@ /** * @internal + * + * @phpstan-type _CommonTypeInfo array{commonType: string, isNullable: bool} */ abstract class AbstractPhpdocToTypeDeclarationFixer extends AbstractFixer implements ConfigurableFixerInterface { - private const REGEX_CLASS = '(?:\\\\?+'.TypeExpression::REGEX_IDENTIFIER + private const REGEX_CLASS = '(?:\\\?+'.TypeExpression::REGEX_IDENTIFIER .'(\\\\'.TypeExpression::REGEX_IDENTIFIER.')*+)'; /** @@ -75,6 +77,10 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setAllowedTypes(['bool']) ->setDefault(true) ->getOption(), + (new FixerOptionBuilder('union_types', 'Fix also union types; turned on by default on PHP >= 8.0.0.')) + ->setAllowedTypes(['bool']) + ->setDefault(\PHP_VERSION_ID >= 8_00_00) + ->getOption(), ]); } @@ -103,7 +109,7 @@ protected function findFunctionDocComment(Tokens $tokens, int $index): ?int } /** - * @return Annotation[] + * @return list */ protected function getAnnotationsFromDocComment(string $name, Tokens $tokens, int $docCommentIndex): array { @@ -123,7 +129,7 @@ protected function getAnnotationsFromDocComment(string $name, Tokens $tokens, in } /** - * @return Token[] + * @return list */ protected function createTypeDeclarationTokens(string $type, bool $isNullable): array { @@ -166,7 +172,7 @@ protected function createTypeDeclarationTokens(string $type, bool $isNullable): abstract protected function createTokensFromRawType(string $type): Tokens; /** - * @return null|array{string, bool} + * @return ?_CommonTypeInfo */ protected function getCommonTypeInfo(TypeExpression $typesExpression, bool $isReturnType): ?array { @@ -201,7 +207,7 @@ protected function getCommonTypeInfo(TypeExpression $typesExpression, bool $isRe return null; } - return [$commonType, $isNullable]; + return ['commonType' => $commonType, 'isNullable' => $isNullable]; } protected function getUnionTypes(TypeExpression $typesExpression, bool $isReturnType): ?string @@ -214,6 +220,10 @@ protected function getUnionTypes(TypeExpression $typesExpression, bool $isReturn return null; } + if (false === $this->configuration['union_types']) { + return null; + } + $types = $typesExpression->getTypes(); $isNullable = $typesExpression->allowsNull(); $unionTypes = []; @@ -236,7 +246,7 @@ protected function getUnionTypes(TypeExpression $typesExpression, bool $isReturn $typeExpression = new TypeExpression($type, null, []); $commonType = $typeExpression->getCommonType(); - if (!$containsOtherThanIterableType && !\in_array($commonType, ['array', 'Traversable', 'iterable'], true)) { + if (!$containsOtherThanIterableType && !\in_array($commonType, ['array', \Traversable::class, 'iterable'], true)) { $containsOtherThanIterableType = true; } if ($isReturnType && !$containsOtherThanEmptyType && !\in_array($commonType, ['null', 'void', 'never'], true)) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocTypesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocTypesFixer.php index c7266c6d..82b8e57f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocTypesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/AbstractPhpdocTypesFixer.php @@ -16,6 +16,7 @@ use PhpCsFixer\DocBlock\Annotation; use PhpCsFixer\DocBlock\DocBlock; +use PhpCsFixer\DocBlock\TypeExpression; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; @@ -31,7 +32,7 @@ abstract class AbstractPhpdocTypesFixer extends AbstractFixer /** * The annotation tags search inside. * - * @var string[] + * @var list */ protected array $tags; @@ -93,26 +94,30 @@ private function fixTypes(Annotation $annotation): void } /** - * @param string[] $types + * @param list $types * - * @return string[] + * @return list */ private function normalizeTypes(array $types): array { - foreach ($types as $index => $type) { - $types[$index] = $this->normalizeType($type); - } - - return $types; - } - - /** - * Prepare the type and normalize it. - */ - private function normalizeType(string $type): string - { - return str_ends_with($type, '[]') - ? $this->normalizeType(substr($type, 0, -2)).'[]' - : $this->normalize($type); + return array_map( + function (string $type): string { + $typeExpression = new TypeExpression($type, null, []); + + $typeExpression->walkTypes(function (TypeExpression $type): void { + if (!$type->isUnionType()) { + $value = $this->normalize($type->toString()); + + // TODO TypeExpression should be immutable and walkTypes method should be changed to mapTypes method + \Closure::bind(static function () use ($type, $value): void { + $type->value = $value; + }, null, TypeExpression::class)(); + } + }); + + return $typeExpression->toString(); + }, + $types + ); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/AbstractProxyFixer.php b/vendor/friendsofphp/php-cs-fixer/src/AbstractProxyFixer.php index d312bae9..96eab156 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/AbstractProxyFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/AbstractProxyFixer.php @@ -100,7 +100,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return FixerInterface[] + * @return list */ abstract protected function createProxyFixers(): array; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Cache/Cache.php b/vendor/friendsofphp/php-cs-fixer/src/Cache/Cache.php index dfa70634..1f53fd2b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Cache/Cache.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Cache/Cache.php @@ -75,7 +75,7 @@ public function toJson(): string 'hashes' => $this->hashes, ]); - if (JSON_ERROR_NONE !== json_last_error()) { + if (JSON_ERROR_NONE !== json_last_error() || false === $json) { throw new \UnexpectedValueException(sprintf( 'Cannot encode cache signature to JSON, error: "%s". If you have non-UTF8 chars in your signature, like in license for `header_comment`, consider enabling `ext-mbstring` or install `symfony/polyfill-mbstring`.', json_last_error_msg() diff --git a/vendor/friendsofphp/php-cs-fixer/src/Cache/CacheManagerInterface.php b/vendor/friendsofphp/php-cs-fixer/src/Cache/CacheManagerInterface.php index 4e82d0c9..b9fb2ff6 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Cache/CacheManagerInterface.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Cache/CacheManagerInterface.php @@ -24,4 +24,6 @@ interface CacheManagerInterface public function needFixing(string $file, string $fileContent): bool; public function setFile(string $file, string $fileContent): void; + + public function setFileHash(string $file, string $hash): void; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Cache/FileCacheManager.php b/vendor/friendsofphp/php-cs-fixer/src/Cache/FileCacheManager.php index 1e3f64dc..d81e91c1 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Cache/FileCacheManager.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Cache/FileCacheManager.php @@ -14,6 +14,8 @@ namespace PhpCsFixer\Cache; +use PhpCsFixer\Tokenizer\CodeHasher; + /** * Class supports caching information about state of fixing files. * @@ -101,9 +103,12 @@ public function needFixing(string $file, string $fileContent): bool public function setFile(string $file, string $fileContent): void { - $file = $this->cacheDirectory->getRelativePathTo($file); + $this->setFileHash($file, $this->calcHash($fileContent)); + } - $hash = $this->calcHash($fileContent); + public function setFileHash(string $file, string $hash): void + { + $file = $this->cacheDirectory->getRelativePathTo($file); if ($this->isDryRun && $this->cache->has($file) && $this->cache->get($file) !== $hash) { $this->cache->clear($file); @@ -136,6 +141,6 @@ private function writeCache(): void private function calcHash(string $content): string { - return md5($content); + return CodeHasher::calculateCodeHash($content); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Cache/NullCacheManager.php b/vendor/friendsofphp/php-cs-fixer/src/Cache/NullCacheManager.php index ff0b6fed..3a5fe991 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Cache/NullCacheManager.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Cache/NullCacheManager.php @@ -16,6 +16,7 @@ /** * @author Andreas Möller + * @author Dariusz Rumiński * * @internal */ @@ -27,4 +28,6 @@ public function needFixing(string $file, string $fileContent): bool } public function setFile(string $file, string $fileContent): void {} + + public function setFileHash(string $file, string $hash): void {} } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Config.php b/vendor/friendsofphp/php-cs-fixer/src/Config.php index 6ed9f5cb..59e5462c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Config.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Config.php @@ -26,7 +26,7 @@ class Config implements ConfigInterface private string $cacheFile = '.php-cs-fixer.cache'; /** - * @var FixerInterface[] + * @var list */ private array $customFixers = []; @@ -57,13 +57,20 @@ class Config implements ConfigInterface * * @var array|bool> */ - private array $rules = ['@PSR12' => true]; + private array $rules; private bool $usingCache = true; public function __construct(string $name = 'default') { - $this->name = $name; + // @TODO 4.0 cleanup + if (Utils::isFutureModeEnabled()) { + $this->name = $name.' (future mode)'; + $this->rules = ['@PER-CS' => true]; + } else { + $this->name = $name; + $this->rules = ['@PSR12' => true]; + } } public function getCacheFile(): string @@ -81,9 +88,7 @@ public function getCustomFixers(): array */ public function getFinder(): iterable { - if (null === $this->finder) { - $this->finder = new Finder(); - } + $this->finder ??= new Finder(); return $this->finder; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/ConfigInterface.php b/vendor/friendsofphp/php-cs-fixer/src/ConfigInterface.php index b46b191b..5308f860 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/ConfigInterface.php +++ b/vendor/friendsofphp/php-cs-fixer/src/ConfigInterface.php @@ -32,7 +32,7 @@ public function getCacheFile(): ?string; /** * Returns the custom fixers to use. * - * @return FixerInterface[] + * @return list */ public function getCustomFixers(): array; @@ -92,7 +92,7 @@ public function getUsingCache(): bool; * * Name of custom fixer should follow `VendorName/rule_name` convention. * - * @param FixerInterface[]|iterable|\Traversable $fixers + * @param iterable $fixers */ public function registerCustomFixers(iterable $fixers): self; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Application.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Application.php index 39fcc587..34f6696c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Application.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Application.php @@ -40,14 +40,15 @@ */ final class Application extends BaseApplication { - public const VERSION = '3.38.2'; - public const VERSION_CODENAME = 'CI Marathon'; + public const NAME = 'PHP CS Fixer'; + public const VERSION = '3.56.1'; + public const VERSION_CODENAME = '15 Keys Accelerate'; private ToolInfo $toolInfo; public function __construct() { - parent::__construct('PHP CS Fixer', self::VERSION); + parent::__construct(self::NAME, self::VERSION); $this->toolInfo = new ToolInfo(); @@ -109,8 +110,13 @@ public function doRun(InputInterface $input, OutputInterface $output): int return $result; } - public function getLongVersion(): string + /** + * @internal + */ + public static function getAbout(bool $decorated = false): string { + $longVersion = sprintf('%s %s', self::NAME, self::VERSION); + $commit = '@git-commit@'; $versionCommit = ''; @@ -118,13 +124,36 @@ public function getLongVersion(): string $versionCommit = substr($commit, 0, 7); } - return implode('', [ - parent::getLongVersion(), + $about = implode('', [ + $longVersion, $versionCommit ? sprintf(' (%s)', $versionCommit) : '', // @phpstan-ignore-line to avoid `Ternary operator condition is always true|false.` self::VERSION_CODENAME ? sprintf(' %s', self::VERSION_CODENAME) : '', // @phpstan-ignore-line to avoid `Ternary operator condition is always true|false.` - ' by Fabien Potencier and Dariusz Ruminski.', - "\nPHP runtime: ".PHP_VERSION.'', + ' by Fabien Potencier, Dariusz Ruminski and contributors.', ]); + + if (false === $decorated) { + return strip_tags($about); + } + + return $about; + } + + /** + * @internal + */ + public static function getAboutWithRuntime(bool $decorated = false): string + { + $about = self::getAbout(true)."\nPHP runtime: ".PHP_VERSION.''; + if (false === $decorated) { + return strip_tags($about); + } + + return $about; + } + + public function getLongVersion(): string + { + return self::getAboutWithRuntime(true); } protected function getDefaultCommands(): array diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/CheckCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/CheckCommand.php index d5c83b72..1e7d7537 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/CheckCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/CheckCommand.php @@ -27,7 +27,10 @@ #[AsCommand(name: 'check', description: 'Checks if configured files/directories comply with configured rules.')] final class CheckCommand extends FixCommand { + /** @var string */ protected static $defaultName = 'check'; + + /** @var string */ protected static $defaultDescription = 'Checks if configured files/directories comply with configured rules.'; public function __construct(ToolInfoInterface $toolInfo) diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DescribeCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DescribeCommand.php index 2b5f9c3b..b8c3ba6c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DescribeCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DescribeCommand.php @@ -15,11 +15,14 @@ namespace PhpCsFixer\Console\Command; use PhpCsFixer\Config; +use PhpCsFixer\Console\Application; use PhpCsFixer\Console\ConfigurationResolver; use PhpCsFixer\Differ\DiffConsoleFormatter; use PhpCsFixer\Differ\FullDiffer; +use PhpCsFixer\Documentation\FixerDocumentGenerator; use PhpCsFixer\Fixer\ConfigurableFixerInterface; use PhpCsFixer\Fixer\DeprecatedFixerInterface; +use PhpCsFixer\Fixer\ExperimentalFixerInterface; use PhpCsFixer\Fixer\FixerInterface; use PhpCsFixer\FixerConfiguration\AliasedFixerOption; use PhpCsFixer\FixerConfiguration\AllowedValueSubset; @@ -52,10 +55,11 @@ #[AsCommand(name: 'describe')] final class DescribeCommand extends Command { + /** @var string */ protected static $defaultName = 'describe'; /** - * @var string[] + * @var ?list */ private $setNames; @@ -93,9 +97,9 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity() && $output instanceof ConsoleOutputInterface) { + if ($output instanceof ConsoleOutputInterface) { $stdErr = $output->getErrorOutput(); - $stdErr->writeln($this->getApplication()->getLongVersion()); + $stdErr->writeln(Application::getAboutWithRuntime(true)); } $resolver = new ConfigurationResolver( @@ -150,24 +154,28 @@ private function describeRule(OutputInterface $output, string $name): void $definition = $fixer->getDefinition(); - $summary = $definition->getSummary(); + $output->writeln(sprintf('Description of the `%s` rule.', $name)); + $output->writeln(''); + + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { + $output->writeln(sprintf('Fixer class: %s.', \get_class($fixer))); + $output->writeln(''); + } if ($fixer instanceof DeprecatedFixerInterface) { $successors = $fixer->getSuccessorsNames(); $message = [] === $successors - ? 'will be removed in the next major version' + ? sprintf('it will be removed in version %d.0', Application::getMajorVersion() + 1) : sprintf('use %s instead', Utils::naturalLanguageJoinWithBackticks($successors)); - $message = Preg::replace('/(`.+?`)/', '$1', $message); - $summary .= sprintf(' DEPRECATED: %s.', $message); - } - - $output->writeln(sprintf('Description of %s rule.', $name)); - if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { - $output->writeln(sprintf('Fixer class: %s.', \get_class($fixer))); + $endMessage = '. '.ucfirst($message); + Utils::triggerDeprecation(new \RuntimeException(str_replace('`', '"', "Rule \"{$name}\" is deprecated{$endMessage}."))); + $message = Preg::replace('/(`[^`]+`)/', '$1', $message); + $output->writeln(sprintf('DEPRECATED: %s.', $message)); + $output->writeln(''); } - $output->writeln($summary); + $output->writeln($definition->getSummary()); $description = $definition->getDescription(); @@ -177,8 +185,15 @@ private function describeRule(OutputInterface $output, string $name): void $output->writeln(''); + if ($fixer instanceof ExperimentalFixerInterface) { + $output->writeln('Fixer applying this rule is EXPERIMENTAL..'); + $output->writeln('It is not covered with backward compatibility promise and may produce unstable or unexpected results.'); + + $output->writeln(''); + } + if ($fixer->isRisky()) { - $output->writeln('Fixer applying this rule is risky.'); + $output->writeln('Fixer applying this rule is RISKY.'); $riskyDescription = $definition->getRiskyDescription(); @@ -242,7 +257,7 @@ private function describeRule(OutputInterface $output, string $name): void $output->writeln(''); } - /** @var CodeSampleInterface[] $codeSamples */ + /** @var list $codeSamples */ $codeSamples = array_filter($definition->getCodeSamples(), static function (CodeSampleInterface $codeSample): bool { if ($codeSample instanceof VersionSpecificCodeSampleInterface) { return $codeSample->isSuitableFor(\PHP_VERSION_ID); @@ -251,9 +266,14 @@ private function describeRule(OutputInterface $output, string $name): void return true; }); - if (0 === \count($codeSamples)) { + if (0 === \count($definition->getCodeSamples())) { $output->writeln([ - 'Fixing examples cannot be demonstrated on the current PHP version.', + 'Fixing examples are not available for this rule.', + '', + ]); + } elseif (0 === \count($codeSamples)) { + $output->writeln([ + 'Fixing examples cannot be demonstrated on the current PHP version.', '', ]); } else { @@ -300,6 +320,24 @@ private function describeRule(OutputInterface $output, string $name): void $output->writeln([$diffFormatter->format($diff, ' %s'), '']); } } + + $ruleSetConfigs = FixerDocumentGenerator::getSetsOfRule($name); + + if ([] !== $ruleSetConfigs) { + ksort($ruleSetConfigs); + $plural = 1 !== \count($ruleSetConfigs) ? 's' : ''; + $output->writeln("Fixer is part of the following rule set{$plural}:"); + + foreach ($ruleSetConfigs as $set => $config) { + if (null !== $config) { + $output->writeln(sprintf('* %s with config: %s', $set, Utils::toString($config))); + } else { + $output->writeln(sprintf('* %s with default config', $set)); + } + } + + $output->writeln(''); + } } private function describeSet(OutputInterface $output, string $name): void @@ -311,15 +349,17 @@ private function describeSet(OutputInterface $output, string $name): void $ruleSetDefinitions = RuleSets::getSetDefinitions(); $fixers = $this->getFixers(); - $output->writeln(sprintf('Description of the %s set.', $ruleSetDefinitions[$name]->getName())); + $output->writeln(sprintf('Description of the `%s` set.', $ruleSetDefinitions[$name]->getName())); + $output->writeln(''); + $output->writeln($this->replaceRstLinks($ruleSetDefinitions[$name]->getDescription())); + $output->writeln(''); if ($ruleSetDefinitions[$name]->isRisky()) { - $output->writeln('This set contains risky rules.'); + $output->writeln('This set contains risky rules.'); + $output->writeln(''); } - $output->writeln(''); - $help = ''; foreach ($ruleSetDefinitions[$name]->getRules() as $rule => $config) { @@ -373,7 +413,7 @@ private function getFixers(): array } /** - * @return string[] + * @return list */ private function getSetNames(): array { @@ -391,23 +431,25 @@ private function getSetNames(): array */ private function describeList(OutputInterface $output, string $type): void { - if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE) { - $describe = [ - 'sets' => $this->getSetNames(), - 'rules' => $this->getFixers(), - ]; - } elseif ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { - $describe = 'set' === $type ? ['sets' => $this->getSetNames()] : ['rules' => $this->getFixers()]; - } else { + if ($output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE) { return; } - /** @var string[] $items */ - foreach ($describe as $list => $items) { - $output->writeln(sprintf('Defined %s:', $list)); + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE || 'set' === $type) { + $output->writeln('Defined sets:'); + + $items = $this->getSetNames(); + foreach ($items as $item) { + $output->writeln(sprintf('* %s', $item)); + } + } + + if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE || 'rule' === $type) { + $output->writeln('Defined rules:'); - foreach ($items as $name => $item) { - $output->writeln(sprintf('* %s', \is_string($name) ? $name : $item)); + $items = array_keys($this->getFixers()); + foreach ($items as $item) { + $output->writeln(sprintf('* %s', $item)); } } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DocumentationCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DocumentationCommand.php index 18c5c317..e1adc987 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DocumentationCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/DocumentationCommand.php @@ -16,7 +16,6 @@ use PhpCsFixer\Documentation\DocumentationLocator; use PhpCsFixer\Documentation\FixerDocumentGenerator; -use PhpCsFixer\Documentation\ListDocumentGenerator; use PhpCsFixer\Documentation\RuleSetDocumentationGenerator; use PhpCsFixer\FixerFactory; use PhpCsFixer\RuleSet\RuleSets; @@ -34,8 +33,17 @@ #[AsCommand(name: 'documentation')] final class DocumentationCommand extends Command { + /** @var string */ protected static $defaultName = 'documentation'; + private Filesystem $filesystem; + + public function __construct(Filesystem $filesystem) + { + parent::__construct(); + $this->filesystem = $filesystem; + } + protected function configure(): void { $this @@ -46,7 +54,6 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $filesystem = new Filesystem(); $locator = new DocumentationLocator(); $fixerFactory = new FixerFactory(); @@ -57,7 +64,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $fixerDocumentGenerator = new FixerDocumentGenerator($locator); $ruleSetDocumentationGenerator = new RuleSetDocumentationGenerator($locator); - $listDocumentGenerator = new ListDocumentGenerator($locator); // Array of existing fixer docs. // We first override existing files, and then we will delete files that are no longer needed. @@ -67,7 +73,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($fixers as $fixer) { $docForFixerRelativePaths[] = $locator->getFixerDocumentationFileRelativePath($fixer); - $filesystem->dumpFile( + $this->filesystem->dumpFile( $locator->getFixerDocumentationFilePath($fixer), $fixerDocumentGenerator->generateFixerDocumentation($fixer) ); @@ -79,12 +85,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int ->in($locator->getFixersDocumentationDirectoryPath()) ->notPath($docForFixerRelativePaths) as $file ) { - $filesystem->remove($file->getPathname()); + $this->filesystem->remove($file->getPathname()); } // Fixer doc. index - $filesystem->dumpFile( + $this->filesystem->dumpFile( $locator->getFixersDocumentationIndexFilePath(), $fixerDocumentGenerator->generateFixersDocumentationIndex($fixers) ); @@ -93,31 +99,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int /** @var SplFileInfo $file */ foreach ((new Finder())->files()->in($locator->getRuleSetsDocumentationDirectoryPath()) as $file) { - $filesystem->remove($file->getPathname()); + $this->filesystem->remove($file->getPathname()); } $paths = []; foreach ($setDefinitions as $name => $definition) { $path = $locator->getRuleSetsDocumentationFilePath($name); - $paths[$name] = $path; - $filesystem->dumpFile($path, $ruleSetDocumentationGenerator->generateRuleSetsDocumentation($definition, $fixers)); + $paths[$path] = $definition; + $this->filesystem->dumpFile($path, $ruleSetDocumentationGenerator->generateRuleSetsDocumentation($definition, $fixers)); } // RuleSet doc. index - $filesystem->dumpFile( + $this->filesystem->dumpFile( $locator->getRuleSetsDocumentationIndexFilePath(), $ruleSetDocumentationGenerator->generateRuleSetsDocumentationIndex($paths) ); - // List file / Appendix - - $filesystem->dumpFile( - $locator->getListingFilePath(), - $listDocumentGenerator->generateListingDocumentation($fixers) - ); - $output->writeln('Docs updated.'); return 0; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/FixCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/FixCommand.php index 65c408fd..7db27641 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/FixCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/FixCommand.php @@ -17,6 +17,7 @@ use PhpCsFixer\Config; use PhpCsFixer\ConfigInterface; use PhpCsFixer\ConfigurationException\InvalidConfigurationException; +use PhpCsFixer\Console\Application; use PhpCsFixer\Console\ConfigurationResolver; use PhpCsFixer\Console\Output\ErrorOutput; use PhpCsFixer\Console\Output\OutputContext; @@ -50,7 +51,10 @@ #[AsCommand(name: 'fix', description: 'Fixes a directory or a file.')] /* final */ class FixCommand extends Command { + /** @var string */ protected static $defaultName = 'fix'; + + /** @var string */ protected static $defaultDescription = 'Fixes a directory or a file.'; private EventDispatcherInterface $eventDispatcher; @@ -157,8 +161,9 @@ public function getHelp(): string * none: disables progress output; * dots: multiline progress output with number of files and percentage on each line. + * bar: single line progress output with number of files and calculated percentage. - If the option is not provided, it defaults to dots unless a config file that disables output is used, in which case it defaults to none. This option has no effect if the verbosity of the command is less than verbose. + If the option is not provided, it defaults to bar unless a config file that disables output is used, in which case it defaults to none. This option has no effect if the verbosity of the command is less than verbose. $ php %command.full_name% --verbose --show-progress=dots @@ -250,9 +255,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int : ('txt' === $reporter->getFormat() ? $output : null); if (null !== $stdErr) { - if (OutputInterface::VERBOSITY_VERBOSE <= $verbosity) { - $stdErr->writeln($this->getApplication()->getLongVersion()); - } + $stdErr->writeln(Application::getAboutWithRuntime(true)); $configFile = $resolver->getConfigFile(); $stdErr->writeln(sprintf('Loaded config %s%s.', $resolver->getConfig()->getName(), null === $configFile ? '' : ' from "'.$configFile.'"')); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/HelpCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/HelpCommand.php index 6dace362..192c735d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/HelpCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/HelpCommand.php @@ -32,6 +32,7 @@ #[AsCommand(name: 'help')] final class HelpCommand extends BaseHelpCommand { + /** @var string */ protected static $defaultName = 'help'; /** diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListFilesCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListFilesCommand.php index 93549116..dcfabd09 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListFilesCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListFilesCommand.php @@ -33,6 +33,7 @@ #[AsCommand(name: 'list-files')] final class ListFilesCommand extends Command { + /** @var string */ protected static $defaultName = 'list-files'; private ConfigInterface $defaultConfig; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListSetsCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListSetsCommand.php index 4279c59a..c1fe5f79 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListSetsCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/ListSetsCommand.php @@ -36,6 +36,7 @@ #[AsCommand(name: 'list-sets')] final class ListSetsCommand extends Command { + /** @var string */ protected static $defaultName = 'list-sets'; protected function configure(): void diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/SelfUpdateCommand.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/SelfUpdateCommand.php index 5e4bddc9..2be3adbc 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Command/SelfUpdateCommand.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Command/SelfUpdateCommand.php @@ -14,6 +14,7 @@ namespace PhpCsFixer\Console\Command; +use PhpCsFixer\Console\Application; use PhpCsFixer\Console\SelfUpdate\NewVersionCheckerInterface; use PhpCsFixer\PharCheckerInterface; use PhpCsFixer\Preg; @@ -36,6 +37,7 @@ #[AsCommand(name: 'self-update')] final class SelfUpdateCommand extends Command { + /** @var string */ protected static $defaultName = 'self-update'; private NewVersionCheckerInterface $versionChecker; @@ -81,9 +83,9 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity() && $output instanceof ConsoleOutputInterface) { + if ($output instanceof ConsoleOutputInterface) { $stdErr = $output->getErrorOutput(); - $stdErr->writeln($this->getApplication()->getLongVersion()); + $stdErr->writeln(Application::getAboutWithRuntime(true)); } if (!$this->toolInfo->isInstalledAsPhar()) { @@ -134,7 +136,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int $remoteTag = $latestVersionOfCurrentMajor; } - $localFilename = realpath($_SERVER['argv'][0]) ?: $_SERVER['argv'][0]; + $localFilename = $_SERVER['argv'][0]; + $realPath = realpath($localFilename); + if (false !== $realPath) { + $localFilename = $realPath; + } if (!is_writable($localFilename)) { $output->writeln(sprintf('No permission to update "%s" file.', $localFilename)); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/ConfigurationResolver.php b/vendor/friendsofphp/php-cs-fixer/src/Console/ConfigurationResolver.php index 5b2a398f..2a895371 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/ConfigurationResolver.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/ConfigurationResolver.php @@ -42,7 +42,6 @@ use PhpCsFixer\Utils; use PhpCsFixer\WhitespacesFixerConfig; use PhpCsFixer\WordMatcher; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Finder\Finder as SymfonyFinder; @@ -95,7 +94,7 @@ final class ConfigurationResolver private $isDryRun; /** - * @var null|FixerInterface[] + * @var null|list */ private $fixers; @@ -315,7 +314,7 @@ public function getDirectory(): DirectoryInterface } /** - * @return FixerInterface[] An array of FixerInterface + * @return list */ public function getFixers(): array { @@ -356,7 +355,7 @@ public function getLinter(): LinterInterface /** * Returns path. * - * @return string[] + * @return list */ public function getPath(): array { @@ -402,18 +401,18 @@ static function (string $rawPath) use ($cwd, $filesystem): string { public function getProgressType(): string { if (null === $this->progress) { - if (OutputInterface::VERBOSITY_VERBOSE <= $this->options['verbosity'] && 'txt' === $this->getFormat()) { + if ('txt' === $this->getFormat()) { $progressType = $this->options['show-progress']; if (null === $progressType) { $progressType = $this->getConfig()->getHideProgress() ? ProgressOutputType::NONE - : ProgressOutputType::DOTS; - } elseif (!\in_array($progressType, ProgressOutputType::AVAILABLE, true)) { + : ProgressOutputType::BAR; + } elseif (!\in_array($progressType, ProgressOutputType::all(), true)) { throw new InvalidConfigurationException(sprintf( 'The progress type "%s" is not defined, supported are %s.', $progressType, - Utils::naturalLanguageJoin(ProgressOutputType::AVAILABLE) + Utils::naturalLanguageJoin(ProgressOutputType::all()) )); } @@ -480,7 +479,7 @@ public function getUsingCache(): bool } } - $this->usingCache = $this->usingCache && ($this->toolInfo->isInstalledAsPhar() || $this->toolInfo->isInstalledByComposer()); + $this->usingCache = $this->usingCache && $this->isCachingAllowedForRuntime(); return $this->usingCache; } @@ -531,7 +530,7 @@ public function configFinderIsOverridden(): bool /** * Compute file candidates for config file. * - * @return string[] + * @return list */ private function computeConfigFiles(): array { @@ -555,7 +554,7 @@ private function computeConfigFiles(): array $configDir = $path[0]; } else { $dirName = pathinfo($path[0], PATHINFO_DIRNAME); - $configDir = $dirName ?: $path[0]; + $configDir = is_dir($dirName) ? $dirName : $path[0]; } $candidates = [ @@ -631,7 +630,7 @@ private function iterableToTraversable(iterable $iterable): \Traversable } /** - * @return array + * @return array */ private function parseRules(): array { @@ -674,7 +673,7 @@ private function parseRules(): array } /** - * @param array $rules + * @param array $rules * * @throws InvalidConfigurationException */ @@ -833,10 +832,10 @@ private function resolveFinder(): iterable $isIntersectionPathMode = self::PATH_MODE_INTERSECTION === $this->options['path-mode']; - $paths = array_filter(array_map( + $paths = array_map( static fn (string $path) => realpath($path), $this->getPath() - )); + ); if (0 === \count($paths)) { if ($isIntersectionPathMode) { @@ -950,4 +949,12 @@ private static function separatedContextLessInclude(string $path): ConfigInterfa return $config; } + + private function isCachingAllowedForRuntime(): bool + { + return $this->toolInfo->isInstalledAsPhar() + || $this->toolInfo->isInstalledByComposer() + || $this->toolInfo->isRunInsideDocker() + || filter_var(getenv('PHP_CS_FIXER_ENFORCE_CACHE'), FILTER_VALIDATE_BOOL); + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/ErrorOutput.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/ErrorOutput.php index 5cb8adb3..79bb57b7 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/ErrorOutput.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/ErrorOutput.php @@ -17,6 +17,7 @@ use PhpCsFixer\Differ\DiffConsoleFormatter; use PhpCsFixer\Error\Error; use PhpCsFixer\Linter\LintingException; +use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Output\OutputInterface; @@ -39,7 +40,7 @@ public function __construct(OutputInterface $output) } /** - * @param Error[] $errors + * @param list $errors */ public function listErrors(string $process, array $errors): void { @@ -86,7 +87,7 @@ public function listErrors(string $process, array $errors): void $this->output->writeln(''); $stackTrace = $e->getTrace(); foreach ($stackTrace as $trace) { - if (isset($trace['class']) && \Symfony\Component\Console\Command\Command::class === $trace['class'] && 'run' === $trace['function']) { + if (isset($trace['class']) && Command::class === $trace['class'] && 'run' === $trace['function']) { $this->output->writeln(' [ ... ]'); break; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/DotsOutput.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/DotsOutput.php index 4df85f81..0e47ae5f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/DotsOutput.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/DotsOutput.php @@ -65,7 +65,7 @@ public function __construct(OutputContext $context) */ public function __sleep(): array { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + throw new \BadMethodCallException('Cannot serialize '.self::class); } /** @@ -76,7 +76,7 @@ public function __sleep(): array */ public function __wakeup(): void { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + throw new \BadMethodCallException('Cannot unserialize '.self::class); } public function onFixerFileProcessed(FixerFileProcessedEvent $event): void diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/PercentageBarOutput.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/PercentageBarOutput.php new file mode 100644 index 00000000..369bed1d --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/PercentageBarOutput.php @@ -0,0 +1,76 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Console\Output\Progress; + +use PhpCsFixer\Console\Output\OutputContext; +use PhpCsFixer\FixerFileProcessedEvent; +use Symfony\Component\Console\Helper\ProgressBar; + +/** + * Output writer to show the progress of a FixCommand using progress bar (percentage). + * + * @internal + */ +final class PercentageBarOutput implements ProgressOutputInterface +{ + /** @readonly */ + private OutputContext $context; + + private ProgressBar $progressBar; + + public function __construct(OutputContext $context) + { + $this->context = $context; + + $this->progressBar = new ProgressBar($context->getOutput(), $this->context->getFilesCount()); + $this->progressBar->setBarCharacter('▓'); // dark shade character \u2593 + $this->progressBar->setEmptyBarCharacter('░'); // light shade character \u2591 + $this->progressBar->setProgressCharacter(''); + $this->progressBar->setFormat('normal'); + + $this->progressBar->start(); + } + + /** + * This class is not intended to be serialized, + * and cannot be deserialized (see __wakeup method). + */ + public function __sleep(): array + { + throw new \BadMethodCallException('Cannot serialize '.self::class); + } + + /** + * Disable the deserialization of the class to prevent attacker executing + * code by leveraging the __destruct method. + * + * @see https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection + */ + public function __wakeup(): void + { + throw new \BadMethodCallException('Cannot unserialize '.self::class); + } + + public function onFixerFileProcessed(FixerFileProcessedEvent $event): void + { + $this->progressBar->advance(1); + + if ($this->progressBar->getProgress() === $this->progressBar->getMaxSteps()) { + $this->context->getOutput()->write("\n\n"); + } + } + + public function printLegend(): void {} +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputFactory.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputFactory.php index 703170fd..b1102e8f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputFactory.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputFactory.php @@ -21,6 +21,15 @@ */ final class ProgressOutputFactory { + /** + * @var array> + */ + private static array $outputTypeMap = [ + ProgressOutputType::NONE => NullOutput::class, + ProgressOutputType::DOTS => DotsOutput::class, + ProgressOutputType::BAR => PercentageBarOutput::class, + ]; + public function create(string $outputType, OutputContext $context): ProgressOutputInterface { if (null === $context->getOutput()) { @@ -36,16 +45,11 @@ public function create(string $outputType, OutputContext $context): ProgressOutp ); } - return ProgressOutputType::NONE === $outputType - ? new NullOutput() - : new DotsOutput($context); + return new self::$outputTypeMap[$outputType]($context); } private function isBuiltInType(string $outputType): bool { - return \in_array($outputType, [ - ProgressOutputType::NONE, - ProgressOutputType::DOTS, - ], true); + return \in_array($outputType, ProgressOutputType::all(), true); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputType.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputType.php index 4c005f89..6f427a46 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputType.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Output/Progress/ProgressOutputType.php @@ -21,9 +21,17 @@ final class ProgressOutputType { public const NONE = 'none'; public const DOTS = 'dots'; + public const BAR = 'bar'; - public const AVAILABLE = [ - self::NONE, - self::DOTS, - ]; + /** + * @return list + */ + public static function all(): array + { + return [ + self::BAR, + self::DOTS, + self::NONE, + ]; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/CheckstyleReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/CheckstyleReporter.php index a6770f60..48daf7b2 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/CheckstyleReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/CheckstyleReporter.php @@ -14,6 +14,7 @@ namespace PhpCsFixer\Console\Report\FixReport; +use PhpCsFixer\Console\Application; use Symfony\Component\Console\Formatter\OutputFormatter; /** @@ -35,7 +36,10 @@ public function generate(ReportSummary $reportSummary): string } $dom = new \DOMDocument('1.0', 'UTF-8'); + + /** @var \DOMElement $checkstyles */ $checkstyles = $dom->appendChild($dom->createElement('checkstyle')); + $checkstyles->setAttribute('version', Application::getAbout()); foreach ($reportSummary->getChanged() as $filePath => $fixResult) { /** @var \DOMElement $file */ diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/GitlabReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/GitlabReporter.php index 0e6c1881..23aad2e8 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/GitlabReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/GitlabReporter.php @@ -14,7 +14,9 @@ namespace PhpCsFixer\Console\Report\FixReport; +use PhpCsFixer\Console\Application; use SebastianBergmann\Diff\Chunk; +use SebastianBergmann\Diff\Diff; use SebastianBergmann\Diff\Parser; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -46,24 +48,20 @@ public function getFormat(): string */ public function generate(ReportSummary $reportSummary): string { + $about = Application::getAbout(); + $report = []; foreach ($reportSummary->getChanged() as $fileName => $change) { - $diffs = $this->diffParser->parse($change['diff']); - $firstChunk = isset($diffs[0]) ? $diffs[0]->getChunks() : []; - $firstChunk = array_shift($firstChunk); foreach ($change['appliedFixers'] as $fixerName) { $report[] = [ - 'check_name' => $fixerName, - 'description' => $fixerName, + 'check_name' => 'PHP-CS-Fixer.'.$fixerName, + 'description' => 'PHP-CS-Fixer.'.$fixerName.' by '.$about, 'categories' => ['Style'], 'fingerprint' => md5($fileName.$fixerName), 'severity' => 'minor', 'location' => [ 'path' => $fileName, - 'lines' => [ - 'begin' => $firstChunk instanceof Chunk ? $firstChunk->getStart() : 0, - 'end' => $firstChunk instanceof Chunk ? $firstChunk->getStartRange() : 0, - ], + 'lines' => self::getLines($this->diffParser->parse($change['diff'])), ], ]; } @@ -73,4 +71,24 @@ public function generate(ReportSummary $reportSummary): string return $reportSummary->isDecoratedOutput() ? OutputFormatter::escape($jsonString) : $jsonString; } + + /** + * @param list $diffs + * + * @return array{begin: int, end: int} + */ + private static function getLines(array $diffs): array + { + if (isset($diffs[0])) { + $firstDiff = $diffs[0]; + + $firstChunk = \Closure::bind(static fn (Diff $diff) => array_shift($diff->chunks), null, $firstDiff)($firstDiff); + + if ($firstChunk instanceof Chunk) { + return \Closure::bind(static fn (Chunk $chunk): array => ['begin' => $chunk->start, 'end' => $chunk->startRange], null, $firstChunk)($firstChunk); + } + } + + return ['begin' => 0, 'end' => 0]; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JsonReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JsonReporter.php index 2bb5b95a..0dc01dba 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JsonReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JsonReporter.php @@ -14,6 +14,7 @@ namespace PhpCsFixer\Console\Report\FixReport; +use PhpCsFixer\Console\Application; use Symfony\Component\Console\Formatter\OutputFormatter; /** @@ -47,11 +48,12 @@ public function generate(ReportSummary $reportSummary): string } $json = [ + 'about' => Application::getAbout(), 'files' => $jsonFiles, 'time' => [ - 'total' => round($reportSummary->getTime() / 1000, 3), + 'total' => round($reportSummary->getTime() / 1_000, 3), ], - 'memory' => round($reportSummary->getMemory() / 1024 / 1024, 3), + 'memory' => round($reportSummary->getMemory() / 1_024 / 1_024, 3), ]; $json = json_encode($json, JSON_THROW_ON_ERROR); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JunitReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JunitReporter.php index 631b28e9..0334bee6 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JunitReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/JunitReporter.php @@ -14,6 +14,7 @@ namespace PhpCsFixer\Console\Report\FixReport; +use PhpCsFixer\Console\Application; use PhpCsFixer\Preg; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -42,6 +43,13 @@ public function generate(ReportSummary $reportSummary): string $testsuite = $testsuites->appendChild($dom->createElement('testsuite')); $testsuite->setAttribute('name', 'PHP CS Fixer'); + $properties = $dom->createElement('properties'); + $property = $dom->createElement('property'); + $property->setAttribute('name', 'about'); + $property->setAttribute('value', Application::getAbout()); + $properties->appendChild($property); + $testsuite->appendChild($properties); + if (\count($reportSummary->getChanged()) > 0) { $this->createFailedTestCases($dom, $testsuite, $reportSummary); } else { @@ -53,7 +61,7 @@ public function generate(ReportSummary $reportSummary): string 'time', sprintf( '%.3f', - $reportSummary->getTime() / 1000 + $reportSummary->getTime() / 1_000 ) ); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/ReporterFactory.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/ReporterFactory.php index e4efd990..86855df2 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/ReporterFactory.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/ReporterFactory.php @@ -37,7 +37,7 @@ public function registerBuiltInReporters(): self foreach (SymfonyFinder::create()->files()->name('*Reporter.php')->in(__DIR__) as $file) { $relativeNamespace = $file->getRelativePath(); $builtInReporters[] = sprintf( - '%s\\%s%s', + '%s\%s%s', __NAMESPACE__, '' !== $relativeNamespace ? $relativeNamespace.'\\' : '', $file->getBasename('.php') diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/TextReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/TextReporter.php index f5394742..31f11f35 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/TextReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/TextReporter.php @@ -95,8 +95,8 @@ private function getFooter(int $time, int $identifiedFiles, int $files, int $mem $identifiedFiles, $files, $isDryRun ? 'files that can be fixed' : 'files', - $time / 1000, - $memory / 1024 / 1024 + $time / 1_000, + $memory / 1_024 / 1_024 ); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/XmlReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/XmlReporter.php index 28236827..59562070 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/XmlReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/FixReport/XmlReporter.php @@ -14,6 +14,7 @@ namespace PhpCsFixer\Console\Report\FixReport; +use PhpCsFixer\Console\Application; use Symfony\Component\Console\Formatter\OutputFormatter; /** @@ -39,6 +40,8 @@ public function generate(ReportSummary $reportSummary): string $root = $dom->createElement('report'); $dom->appendChild($root); + $root->appendChild($this->createAboutElement($dom, Application::getAbout())); + $filesXML = $dom->createElement('files'); $root->appendChild($filesXML); @@ -99,7 +102,7 @@ private function createDiffElement(\DOMDocument $dom, string $diff): \DOMElement private function createTimeElement(float $time, \DOMDocument $dom): \DOMElement { - $time = round($time / 1000, 3); + $time = round($time / 1_000, 3); $timeXML = $dom->createElement('time'); $timeXML->setAttribute('unit', 's'); @@ -112,7 +115,7 @@ private function createTimeElement(float $time, \DOMDocument $dom): \DOMElement private function createMemoryElement(float $memory, \DOMDocument $dom): \DOMElement { - $memory = round($memory / 1024 / 1024, 3); + $memory = round($memory / 1_024 / 1_024, 3); $memoryXML = $dom->createElement('memory'); $memoryXML->setAttribute('value', (string) $memory); @@ -120,4 +123,12 @@ private function createMemoryElement(float $memory, \DOMDocument $dom): \DOMElem return $memoryXML; } + + private function createAboutElement(\DOMDocument $dom, string $about): \DOMElement + { + $XML = $dom->createElement('about'); + $XML->setAttribute('value', $about); + + return $XML; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/JsonReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/JsonReporter.php index 956fb131..ceebd89e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/JsonReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/JsonReporter.php @@ -32,7 +32,7 @@ public function generate(ReportSummary $reportSummary): string { $sets = $reportSummary->getSets(); - usort($sets, static fn (RuleSetDescriptionInterface $a, RuleSetDescriptionInterface $b): int => strcmp($a->getName(), $b->getName())); + usort($sets, static fn (RuleSetDescriptionInterface $a, RuleSetDescriptionInterface $b): int => $a->getName() <=> $b->getName()); $json = ['sets' => []]; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/ReporterFactory.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/ReporterFactory.php index 45f2a26f..0d0ae6da 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/ReporterFactory.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/ReporterFactory.php @@ -39,7 +39,7 @@ public function registerBuiltInReporters(): self foreach (SymfonyFinder::create()->files()->name('*Reporter.php')->in(__DIR__) as $file) { $relativeNamespace = $file->getRelativePath(); $builtInReporters[] = sprintf( - '%s\\%s%s', + '%s\%s%s', __NAMESPACE__, '' !== $relativeNamespace ? $relativeNamespace.'\\' : '', $file->getBasename('.php') diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/TextReporter.php b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/TextReporter.php index 7804b93b..9c851ef3 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/TextReporter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/Report/ListSetsReport/TextReporter.php @@ -32,7 +32,7 @@ public function generate(ReportSummary $reportSummary): string { $sets = $reportSummary->getSets(); - usort($sets, static fn (RuleSetDescriptionInterface $a, RuleSetDescriptionInterface $b): int => strcmp($a->getName(), $b->getName())); + usort($sets, static fn (RuleSetDescriptionInterface $a, RuleSetDescriptionInterface $b): int => $a->getName() <=> $b->getName()); $output = ''; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClient.php b/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClient.php index e2268d7f..10995cfb 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClient.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClient.php @@ -19,12 +19,12 @@ */ final class GithubClient implements GithubClientInterface { + private string $url = 'https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/tags'; + public function getTags(): array { - $url = 'https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/tags'; - $result = @file_get_contents( - $url, + $this->url, false, stream_context_create([ 'http' => [ @@ -34,18 +34,29 @@ public function getTags(): array ); if (false === $result) { - throw new \RuntimeException(sprintf('Failed to load tags at "%s".', $url)); + throw new \RuntimeException(sprintf('Failed to load tags at "%s".', $this->url)); } + /** + * @var list + */ $result = json_decode($result, true); if (JSON_ERROR_NONE !== json_last_error()) { throw new \RuntimeException(sprintf( 'Failed to read response from "%s" as JSON: %s.', - $url, + $this->url, json_last_error_msg() )); } - return $result; + return array_map( + static fn (array $tagData): string => $tagData['name'], + $result + ); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClientInterface.php b/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClientInterface.php index 38178a22..27728327 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClientInterface.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/GithubClientInterface.php @@ -20,12 +20,7 @@ interface GithubClientInterface { /** - * @return list + * @return list */ public function getTags(): array; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/NewVersionChecker.php b/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/NewVersionChecker.php index 06bd1229..fc28677c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/NewVersionChecker.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/SelfUpdate/NewVersionChecker.php @@ -28,7 +28,7 @@ final class NewVersionChecker implements NewVersionCheckerInterface private VersionParser $versionParser; /** - * @var null|string[] + * @var null|list */ private $availableVersions; @@ -82,9 +82,7 @@ private function retrieveAvailableVersions(): void return; } - foreach ($this->githubClient->getTags() as $tag) { - $version = $tag['name']; - + foreach ($this->githubClient->getTags() as $version) { try { $this->versionParser->normalize($version); @@ -96,6 +94,9 @@ private function retrieveAvailableVersions(): void } } - $this->availableVersions = Semver::rsort($this->availableVersions); + $versions = Semver::rsort($this->availableVersions); + \assert(array_is_list($versions)); // Semver::rsort provides soft `array` type, let's validate and ensure proper type for SCA + + $this->availableVersions = $versions; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Console/WarningsDetector.php b/vendor/friendsofphp/php-cs-fixer/src/Console/WarningsDetector.php index dac182b8..a58a0bed 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Console/WarningsDetector.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Console/WarningsDetector.php @@ -27,7 +27,7 @@ final class WarningsDetector private ToolInfoInterface $toolInfo; /** - * @var string[] + * @var list */ private array $warnings = []; @@ -60,7 +60,7 @@ public function detectOldVendor(): void } /** - * @return string[] + * @return list */ public function getWarnings(): array { @@ -68,9 +68,9 @@ public function getWarnings(): array return []; } - return array_unique(array_merge( + return array_values(array_unique(array_merge( $this->warnings, - ['If you need help while solving warnings, ask at https://gitter.im/PHP-CS-Fixer, we will help you!'] - )); + ['If you need help while solving warnings, ask at https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/discussions/, we will help you!'] + ))); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Annotation.php b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Annotation.php index c4a0444c..7c331a52 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Annotation.php +++ b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Annotation.php @@ -29,7 +29,7 @@ final class Annotation /** * All the annotation tag names with types. * - * @var string[] + * @var list */ private static array $tags = [ 'method', @@ -46,7 +46,7 @@ final class Annotation /** * The lines that make up the annotation. * - * @var Line[] + * @var array */ private array $lines; @@ -81,7 +81,7 @@ final class Annotation /** * The cached types. * - * @var null|string[] + * @var null|list */ private $types; @@ -91,16 +91,16 @@ final class Annotation private $namespace; /** - * @var NamespaceUseAnalysis[] + * @var list */ private array $namespaceUses; /** * Create a new line instance. * - * @param Line[] $lines - * @param null|NamespaceAnalysis $namespace - * @param NamespaceUseAnalysis[] $namespaceUses + * @param array $lines + * @param null|NamespaceAnalysis $namespace + * @param list $namespaceUses */ public function __construct(array $lines, $namespace = null, array $namespaceUses = []) { @@ -108,10 +108,8 @@ public function __construct(array $lines, $namespace = null, array $namespaceUse $this->namespace = $namespace; $this->namespaceUses = $namespaceUses; - $keys = array_keys($lines); - - $this->start = $keys[0]; - $this->end = end($keys); + $this->start = array_key_first($lines); + $this->end = array_key_last($lines); } /** @@ -125,7 +123,7 @@ public function __toString(): string /** * Get all the annotation tag names with types. * - * @return string[] + * @return list */ public static function getTagsWithTypes(): array { @@ -192,7 +190,7 @@ public function getVariableName() /** * Get the types associated with this annotation. * - * @return string[] + * @return list */ public function getTypes(): array { @@ -209,7 +207,7 @@ public function getTypes(): array /** * Set the types associated with this annotation. * - * @param string[] $types + * @param list $types */ public function setTypes(array $types): void { @@ -223,7 +221,7 @@ public function setTypes(array $types): void /** * Get the normalized types associated with this annotation, so they can easily be compared. * - * @return string[] + * @return list */ public function getNormalizedTypes(): array { @@ -290,7 +288,7 @@ private function getTypesContent(): ?string } $matchingResult = Preg::match( - '{^(?:\s*\*|/\*\*)[\s\*]*@'.$name.'\s+'.TypeExpression::REGEX_TYPES.'(?:(?:[*\h\v]|\&?[\.\$]).*)?\r?$}is', + '{^(?:\h*\*|/\*\*)[\h*]*@'.$name.'\h+'.TypeExpression::REGEX_TYPES.'(?:(?:[*\h\v]|\&?[\.\$]).*)?\r?$}is', $this->lines[0]->getContent(), $matches ); diff --git a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Line.php b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Line.php index 1e6fa5b9..9ef4a087 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Line.php +++ b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/Line.php @@ -59,7 +59,7 @@ public function getContent(): string */ public function containsUsefulContent(): bool { - return Preg::match('/\\*\s*\S+/', $this->content) && '' !== trim(str_replace(['/', '*'], ' ', $this->content)); + return Preg::match('/\*\s*\S+/', $this->content) && '' !== trim(str_replace(['/', '*'], ' ', $this->content)); } /** @@ -69,7 +69,7 @@ public function containsUsefulContent(): bool */ public function containsATag(): bool { - return Preg::match('/\\*\s*@/', $this->content); + return Preg::match('/\*\s*@/', $this->content); } /** diff --git a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TagComparator.php b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TagComparator.php index 578fd3a7..c5a3a896 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TagComparator.php +++ b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TagComparator.php @@ -28,6 +28,8 @@ final class TagComparator /** * Groups of tags that should be allowed to immediately follow each other. * + * @var list> + * * @internal */ public const DEFAULT_GROUPS = [ @@ -40,7 +42,7 @@ final class TagComparator /** * Should the given tags be kept together, or kept apart? * - * @param string[][] $groups + * @param list> $groups */ public static function shouldBeTogether(Tag $first, Tag $second, array $groups = self::DEFAULT_GROUPS): bool { diff --git a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TypeExpression.php b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TypeExpression.php index 505e0b3d..4bb74464 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TypeExpression.php +++ b/vendor/friendsofphp/php-cs-fixer/src/DocBlock/TypeExpression.php @@ -20,6 +20,8 @@ use PhpCsFixer\Utils; /** + * @author Michael Vorisek + * * @internal */ final class TypeExpression @@ -44,6 +46,11 @@ final class TypeExpression )*+ )'; + /** + * Based on: + * - https://github.com/phpstan/phpdoc-parser/blob/1.26.0/doc/grammars/type.abnf fuzzing grammar + * - and https://github.com/phpstan/phpdoc-parser/blob/1.26.0/src/Parser/PhpDocParser.php parser impl. + */ private const REGEX_TYPE = '(?(?x) # single type (?\??\h*) (?: @@ -51,20 +58,45 @@ final class TypeExpression (?(?i)(?:array|list|object)(?-i)\h*\{\h*) (? (? - (?(?:(?&constant)|(?&identifier))\h*\??\h*:\h*|) + (?(?:(?&constant)|(?&identifier)|(?&name))\h*\??\h*:\h*|) (?(?&types_inner)) ) (?: \h*,\h* (?&array_shape_inner) - )* + )*+ (?:\h*,\h*)? |) \h*\} ) | - (? # callable syntax, e.g. `callable(string, int...): bool` - (?(?&name)\h*\(\h*) + (? # callable syntax, e.g. `callable(string, int...): bool`, `\Closure(T, int): T` + (?(?&name)) + (? + (?\h*<\h*) + (? + (? + (? + (?&identifier) + ) + (? # template bound + \h+(?i)(?of|as)(?-i)\h+ + (?(?&types_inner)) + |) + (? # template default + \h*=\h* + (?(?&types_inner)) + |) + ) + (?: + \h*,\h* + (?&callable_template_inner) + )*+ + ) + \h*> + (?=\h*\() + |) + (?\h*\(\h*) (? (? (?(?&types_inner)) @@ -76,7 +108,7 @@ final class TypeExpression (?: \h*,\h* (?&callable_argument) - )* + )*+ (?:\h*,\h*)? |) \h*\) @@ -93,7 +125,7 @@ final class TypeExpression (?: \h*,\h* (?&types_inner) - )* + )*+ (?:\h*,\h*)? ) \h*> @@ -115,8 +147,8 @@ final class TypeExpression (?:\.(?&constant_digits)|(?<=\d)\.)?+ (?:e[+-]?(?&constant_digits))?+ ) - | \'(?:[^\'\\\\]|\\\\.)*+\' - | "(?:[^"\\\\]|\\\\.)*+" + | \'(?:[^\'\\\]|\\\.)*+\' + | "(?:[^"\\\]|\\\.)*+" (?-i) ) | @@ -127,7 +159,7 @@ final class TypeExpression ) | (? # full name, e.g.: `int`, `\DateTime`, `\Foo\Bar`, `positive-int` - \\\\?+ + \\\?+ (?'.self::REGEX_IDENTIFIER.') (?:[\\\\\-](?&identifier))*+ ) @@ -164,13 +196,13 @@ final class TypeExpression (\h*\[\h*\])* ) (?:(?=1)0 - (? + (?(?> (?&type) (?: \h*[|&]\h* (?&type) )*+ - ) + )) |) )'; @@ -188,12 +220,12 @@ final class TypeExpression private ?NamespaceAnalysis $namespace; /** - * @var NamespaceUseAnalysis[] + * @var list */ private array $namespaceUses; /** - * @param NamespaceUseAnalysis[] $namespaceUses + * @param list $namespaceUses */ public function __construct(string $value, ?NamespaceAnalysis $namespace, array $namespaceUses) { @@ -210,7 +242,7 @@ public function toString(): string } /** - * @return string[] + * @return list */ public function getTypes(): array { @@ -239,7 +271,7 @@ public function getTypesGlue(): string */ public function walkTypes(\Closure $callback): void { - foreach ($this->innerTypeExpressions as [ + foreach (array_reverse($this->innerTypeExpressions) as [ 'start_index' => $startIndex, 'expression' => $inner, ]) { @@ -375,8 +407,16 @@ private function parse(): void $matches['generic_types'][0] ); } elseif ('' !== ($matches['callable'][0] ?? '') && $matches['callable'][1] === $nullableLength) { + $this->parseCallableTemplateInnerTypes( + $index + \strlen($matches['callable_name'][0]) + + \strlen($matches['callable_template_start'][0]), + $matches['callable_template_inners'][0] + ); + $this->parseCallableArgumentTypes( - $index + \strlen($matches['callable_start'][0]), + $index + \strlen($matches['callable_name'][0]) + + \strlen($matches['callable_template'][0]) + + \strlen($matches['callable_start'][0]), $matches['callable_arguments'][0] ); @@ -452,6 +492,49 @@ private function parseCommaSeparatedInnerTypes(int $startIndex, string $value): } } + private function parseCallableTemplateInnerTypes(int $startIndex, string $value): void + { + $index = 0; + while (\strlen($value) !== $index) { + Preg::match( + '{\G(?:(?=1)0'.self::REGEX_TYPES.'|(?<_callable_template_inner>(?&callable_template_inner))(?:\h*,\h*|$))}', + $value, + $prematches, + 0, + $index + ); + $consumedValue = $prematches['_callable_template_inner']; + $consumedValueLength = \strlen($consumedValue); + $consumedCommaLength = \strlen($prematches[0]) - $consumedValueLength; + + $addedPrefix = 'Closure<'; + Preg::match( + '{^'.self::REGEX_TYPES.'$}', + $addedPrefix.$consumedValue.'>(): void', + $matches, + PREG_OFFSET_CAPTURE + ); + + if ('' !== $matches['callable_template_inner_b'][0]) { + $this->innerTypeExpressions[] = [ + 'start_index' => $startIndex + $index + $matches['callable_template_inner_b_types'][1] + - \strlen($addedPrefix), + 'expression' => $this->inner($matches['callable_template_inner_b_types'][0]), + ]; + } + + if ('' !== $matches['callable_template_inner_d'][0]) { + $this->innerTypeExpressions[] = [ + 'start_index' => $startIndex + $index + $matches['callable_template_inner_d_types'][1] + - \strlen($addedPrefix), + 'expression' => $this->inner($matches['callable_template_inner_d_types'][0]), + ]; + } + + $index += $consumedValueLength + $consumedCommaLength; + } + } + private function parseCallableArgumentTypes(int $startIndex, string $value): void { $index = 0; @@ -508,7 +591,8 @@ private function parseArrayShapeInnerTypes(int $startIndex, string $value): void ); $this->innerTypeExpressions[] = [ - 'start_index' => $startIndex + $index + $matches['array_shape_inner_value'][1] - \strlen($addedPrefix), + 'start_index' => $startIndex + $index + $matches['array_shape_inner_value'][1] + - \strlen($addedPrefix), 'expression' => $this->inner($matches['array_shape_inner_value'][0]), ]; @@ -594,7 +678,7 @@ private function normalize(string $type): string } /** - * @return array + * @return array */ private function getAliases(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/DocLexer.php b/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/DocLexer.php index b451d00b..ef1878ea 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/DocLexer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/DocLexer.php @@ -75,7 +75,7 @@ final class DocLexer private int $peek = 0; - private ?string $regex; + private ?string $regex = null; public function setInput(string $input): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Token.php b/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Token.php index 314df6b2..56cb83e4 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Token.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Token.php @@ -66,7 +66,7 @@ public function getPosition(): int /** * Returns whether the token type is one of the given types. * - * @param int|int[] $types + * @param int|list $types */ public function isType($types): bool { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Tokens.php b/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Tokens.php index a388cf4c..96f61e3e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Tokens.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Doctrine/Annotation/Tokens.php @@ -14,7 +14,6 @@ namespace PhpCsFixer\Doctrine\Annotation; -use PhpCsFixer\Doctrine\Annotation\Token as AnnotationToken; use PhpCsFixer\Preg; use PhpCsFixer\Tokenizer\Token as PhpToken; @@ -28,7 +27,7 @@ final class Tokens extends \SplFixedArray { /** - * @param string[] $ignoredTags + * @param list $ignoredTags * * @throws \InvalidArgumentException */ @@ -101,14 +100,14 @@ public static function createFromDocComment(PhpToken $input, array $ignoredTags } $lastTokenEndIndex = 0; - foreach (\array_slice($scannedTokens, 0, $nbScannedTokensToUse) as $token) { - if ($token->isType(DocLexer::T_STRING)) { - $token = new AnnotationToken( - $token->getType(), - '"'.str_replace('"', '""', $token->getContent()).'"', - $token->getPosition() - ); - } + foreach (\array_slice($scannedTokens, 0, $nbScannedTokensToUse) as $scannedToken) { + $token = $scannedToken->isType(DocLexer::T_STRING) + ? new Token( + $scannedToken->getType(), + '"'.str_replace('"', '""', $scannedToken->getContent()).'"', + $scannedToken->getPosition() + ) + : $scannedToken; $missingTextLength = $token->getPosition() - $lastTokenEndIndex; if ($missingTextLength > 0) { @@ -139,8 +138,8 @@ public static function createFromDocComment(PhpToken $input, array $ignoredTags /** * Create token collection from array. * - * @param Token[] $array the array to import - * @param ?bool $saveIndices save the numeric indices used in the original array, default is yes + * @param array $array the array to import + * @param ?bool $saveIndices save the numeric indices used in the original array, default is yes */ public static function fromArray($array, $saveIndices = null): self { @@ -247,7 +246,7 @@ public function insertAt(int $index, Token $token): void public function offsetSet($index, $token): void { if (null === $token) { - throw new \InvalidArgumentException('Token must be an instance of PhpCsFixer\\Doctrine\\Annotation\\Token, "null" given.'); + throw new \InvalidArgumentException('Token must be an instance of PhpCsFixer\Doctrine\Annotation\Token, "null" given.'); } if (!$token instanceof Token) { @@ -257,7 +256,7 @@ public function offsetSet($index, $token): void $type = \get_class($token); } - throw new \InvalidArgumentException(sprintf('Token must be an instance of PhpCsFixer\\Doctrine\\Annotation\\Token, "%s" given.', $type)); + throw new \InvalidArgumentException(sprintf('Token must be an instance of PhpCsFixer\Doctrine\Annotation\Token, "%s" given.', $type)); } parent::offsetSet($index, $token); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Documentation/DocumentationLocator.php b/vendor/friendsofphp/php-cs-fixer/src/Documentation/DocumentationLocator.php index f384e48c..3769c4fd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Documentation/DocumentationLocator.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Documentation/DocumentationLocator.php @@ -43,7 +43,7 @@ public function getFixersDocumentationIndexFilePath(): string public function getFixerDocumentationFilePath(FixerInterface $fixer): string { return $this->getFixersDocumentationDirectoryPath().'/'.Preg::replaceCallback( - '/^.*\\\\(.+)\\\\(.+)Fixer$/', + '/^.*\\\(.+)\\\(.+)Fixer$/', static fn (array $matches): string => Utils::camelCaseToUnderscore($matches[1]).'/'.Utils::camelCaseToUnderscore($matches[2]), \get_class($fixer) ).'.rst'; @@ -73,11 +73,6 @@ public function getRuleSetsDocumentationFilePath(string $name): string return $this->getRuleSetsDocumentationDirectoryPath().'/'.str_replace(':risky', 'Risky', ucfirst(substr($name, 1))).'.rst'; } - public function getListingFilePath(): string - { - return $this->path.'/list.rst'; - } - public function getUsageFilePath(): string { return $this->path.'/usage.rst'; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Documentation/FixerDocumentGenerator.php b/vendor/friendsofphp/php-cs-fixer/src/Documentation/FixerDocumentGenerator.php index f5540d46..6fd40467 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Documentation/FixerDocumentGenerator.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Documentation/FixerDocumentGenerator.php @@ -18,6 +18,7 @@ use PhpCsFixer\Differ\FullDiffer; use PhpCsFixer\Fixer\ConfigurableFixerInterface; use PhpCsFixer\Fixer\DeprecatedFixerInterface; +use PhpCsFixer\Fixer\ExperimentalFixerInterface; use PhpCsFixer\Fixer\FixerInterface; use PhpCsFixer\FixerConfiguration\AliasedFixerOption; use PhpCsFixer\FixerConfiguration\AllowedValueSubset; @@ -89,6 +90,19 @@ public function generateFixerDocumentation(FixerInterface $fixer): string } } + $experimentalDescription = ''; + + if ($fixer instanceof ExperimentalFixerInterface) { + $experimentalDescriptionRaw = RstUtils::toRst('Rule is not covered with backward compatibility promise, use it at your own risk. Rule\'s behaviour may be changed at any point, including rule\'s name; its options\' names, availability and allowed values; its default configuration. Rule may be even removed without prior notice. Feel free to provide feedback and help with determining final state of the rule.', 0); + $experimentalDescription = <<getRiskyDescription(); @@ -111,12 +125,16 @@ public function generateFixerDocumentation(FixerInterface $fixer): string } $warningsHeaderLine = str_repeat('-', \strlen($warningsHeader)); - $doc .= "\n\n".implode("\n", array_filter([ - $warningsHeader, - $warningsHeaderLine, - $deprecationDescription, - $riskyDescription, - ])); + $doc .= "\n\n".implode("\n", array_filter( + [ + $warningsHeader, + $warningsHeaderLine, + $deprecationDescription, + $experimentalDescription, + $riskyDescription, + ], + static fn (string $text): bool => '' !== $text + )); } if ($fixer instanceof ConfigurableFixerInterface) { @@ -203,15 +221,7 @@ public function generateFixerDocumentation(FixerInterface $fixer): string } } - $ruleSetConfigs = []; - - foreach (RuleSets::getSetDefinitionNames() as $set) { - $ruleSet = new RuleSet([$set => true]); - - if ($ruleSet->hasRule($name)) { - $ruleSetConfigs[$set] = $ruleSet->getRuleConfiguration($name); - } - } + $ruleSetConfigs = self::getSetsOfRule($name); if ([] !== $ruleSetConfigs) { $plural = 1 !== \count($ruleSetConfigs) ? 's' : ''; @@ -243,21 +253,50 @@ public function generateFixerDocumentation(FixerInterface $fixer): string $fileName = $reflectionObject->getFileName(); $fileName = str_replace('\\', '/', $fileName); $fileName = substr($fileName, strrpos($fileName, '/src/Fixer/') + 1); - $fileName = "`{$className} <./../{$fileName}>`_"; + $fileName = "`{$className} <./../../../{$fileName}>`_"; + + $testFileName = Preg::replace('~.*\K/src/(?=Fixer/)~', '/tests/', $fileName); + $testFileName = Preg::replace('~PhpCsFixer\\\\\\\\\K(?=Fixer\\\\\\\)~', 'Tests\\\\\\\\', $testFileName); + $testFileName = Preg::replace('~(?= <|\.php>)~', 'Test', $testFileName); $doc .= <<', $doc); + return "{$doc}\n"; } /** - * @param FixerInterface[] $fixers + * @internal + * + * @return array> + */ + public static function getSetsOfRule(string $ruleName): array + { + $ruleSetConfigs = []; + + foreach (RuleSets::getSetDefinitionNames() as $set) { + $ruleSet = new RuleSet([$set => true]); + + if ($ruleSet->hasRule($ruleName)) { + $ruleSetConfigs[$set] = $ruleSet->getRuleConfiguration($ruleName); + } + } + + return $ruleSetConfigs; + } + + /** + * @param list $fixers */ public function generateFixersDocumentationIndex(array $fixers): string { @@ -267,7 +306,7 @@ public function generateFixersDocumentationIndex(array $fixers): string 'Phpdoc' => 'PHPDoc', ]; - usort($fixers, static fn (FixerInterface $a, FixerInterface $b): int => strcmp(\get_class($a), \get_class($b))); + usort($fixers, static fn (FixerInterface $a, FixerInterface $b): int => \get_class($a) <=> \get_class($b)); $documentation = <<<'RST' ======================= @@ -278,7 +317,7 @@ public function generateFixersDocumentationIndex(array $fixers): string $currentGroup = null; foreach ($fixers as $fixer) { - $namespace = Preg::replace('/^.*\\\\(.+)\\\\.+Fixer$/', '$1', \get_class($fixer)); + $namespace = Preg::replace('/^.*\\\(.+)\\\.+Fixer$/', '$1', \get_class($fixer)); $group = $overrideGroups[$namespace] ?? Preg::replace('/(?<=[[:lower:]])(?=[[:upper:]])/', ' ', $namespace); if ($group !== $currentGroup) { @@ -296,6 +335,10 @@ public function generateFixersDocumentationIndex(array $fixers): string $attributes[] = 'deprecated'; } + if ($fixer instanceof ExperimentalFixerInterface) { + $attributes[] = 'experimental'; + } + if ($fixer->isRisky()) { $attributes[] = 'risky'; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Documentation/ListDocumentGenerator.php b/vendor/friendsofphp/php-cs-fixer/src/Documentation/ListDocumentGenerator.php deleted file mode 100644 index 51637ecb..00000000 --- a/vendor/friendsofphp/php-cs-fixer/src/Documentation/ListDocumentGenerator.php +++ /dev/null @@ -1,170 +0,0 @@ - - * Dariusz Rumiński - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace PhpCsFixer\Documentation; - -use PhpCsFixer\Console\Command\HelpCommand; -use PhpCsFixer\Fixer\ConfigurableFixerInterface; -use PhpCsFixer\Fixer\DeprecatedFixerInterface; -use PhpCsFixer\Fixer\FixerInterface; -use PhpCsFixer\FixerConfiguration\AliasedFixerOption; -use PhpCsFixer\FixerConfiguration\AllowedValueSubset; -use PhpCsFixer\FixerConfiguration\DeprecatedFixerOptionInterface; -use PhpCsFixer\RuleSet\RuleSet; -use PhpCsFixer\RuleSet\RuleSets; -use PhpCsFixer\Utils; - -/** - * @internal - */ -final class ListDocumentGenerator -{ - private DocumentationLocator $locator; - - public function __construct(DocumentationLocator $locator) - { - $this->locator = $locator; - } - - /** - * @param FixerInterface[] $fixers - */ - public function generateListingDocumentation(array $fixers): string - { - usort( - $fixers, - static fn (FixerInterface $fixer1, FixerInterface $fixer2): int => strnatcasecmp($fixer1->getName(), $fixer2->getName()) - ); - - $documentation = <<<'RST' - ======================= - List of Available Rules - ======================= - - RST; - foreach ($fixers as $fixer) { - $name = $fixer->getName(); - $definition = $fixer->getDefinition(); - $path = './rules/'.$this->locator->getFixerDocumentationFileRelativePath($fixer); - - $documentation .= "\n- `{$name} <{$path}>`_\n"; - $documentation .= "\n ".str_replace('`', '``', $definition->getSummary())."\n"; - - $description = $definition->getDescription(); - - if (null !== $description) { - $documentation .= "\n ".RstUtils::toRst($description, 3)."\n"; - } - - if ($fixer instanceof DeprecatedFixerInterface) { - $documentation .= "\n *warning deprecated*"; - $alternatives = $fixer->getSuccessorsNames(); - - if (0 !== \count($alternatives)) { - $documentation .= RstUtils::toRst(sprintf( - ' Use %s instead.', - Utils::naturalLanguageJoinWithBackticks($alternatives) - ), 3); - } - - $documentation .= "\n"; - } - - if ($fixer->isRisky()) { - $documentation .= "\n *warning risky* ".RstUtils::toRst($definition->getRiskyDescription(), 3)."\n"; - } - - if ($fixer instanceof ConfigurableFixerInterface) { - $documentation .= "\n Configuration options:\n"; - $configurationDefinition = $fixer->getConfigurationDefinition(); - - foreach ($configurationDefinition->getOptions() as $option) { - $documentation .= "\n - | ``{$option->getName()}``"; - $documentation .= "\n | ".RstUtils::ensureProperInlineCode($option->getDescription()); - - if ($option instanceof DeprecatedFixerOptionInterface) { - $deprecationMessage = RstUtils::toRst($option->getDeprecationMessage(), 3); - $documentation .= "\n | warning:: This option is deprecated and will be removed in the next major version. {$deprecationMessage}"; - } - - if ($option instanceof AliasedFixerOption) { - $documentation .= "\n | note:: The previous name of this option was ``{$option->getAlias()}`` but it is now deprecated and will be removed in the next major version."; - } - - $allowed = HelpCommand::getDisplayableAllowedValues($option); - - if (null === $allowed) { - $allowedKind = 'Allowed types'; - $allowed = array_map( - static fn ($value): string => '``'.$value.'``', - $option->getAllowedTypes(), - ); - } else { - $allowedKind = 'Allowed values'; - $allowed = array_map(static fn ($value): string => $value instanceof AllowedValueSubset - ? 'a subset of ``'.Utils::toString($value->getAllowedValues()).'``' - : '``'.Utils::toString($value).'``', $allowed); - } - - $allowed = Utils::naturalLanguageJoin($allowed, ''); - $documentation .= "\n | {$allowedKind}: {$allowed}"; - - if ($option->hasDefault()) { - $default = Utils::toString($option->getDefault()); - $documentation .= "\n | Default value: ``{$default}``"; - } else { - $documentation .= "\n | This option is required."; - } - } - - $documentation .= "\n\n"; - } - - $ruleSetConfigs = []; - - foreach (RuleSets::getSetDefinitionNames() as $set) { - $ruleSet = new RuleSet([$set => true]); - - if ($ruleSet->hasRule($name)) { - $ruleSetConfigs[$set] = $ruleSet->getRuleConfiguration($name); - } - } - - if ([] !== $ruleSetConfigs) { - $plural = 1 !== \count($ruleSetConfigs) ? 's' : ''; - - $documentation .= "\n Part of rule set{$plural} "; - - foreach ($ruleSetConfigs as $set => $config) { - $ruleSetPath = $this->locator->getRuleSetsDocumentationFilePath($set); - $ruleSetPath = substr($ruleSetPath, strrpos($ruleSetPath, '/')); - - $documentation .= "`{$set} <./ruleSets{$ruleSetPath}>`_ "; - } - - $documentation = rtrim($documentation)."\n"; - } - - $reflectionObject = new \ReflectionObject($fixer); - $className = str_replace('\\', '\\\\', $reflectionObject->getName()); - $fileName = $reflectionObject->getFileName(); - $fileName = str_replace('\\', '/', $fileName); - $fileName = substr($fileName, strrpos($fileName, '/src/Fixer/') + 1); - $fileName = "Source: `{$className} <./../{$fileName}>`_"; - $documentation .= "\n ".$fileName; - } - - return $documentation."\n"; - } -} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Documentation/RuleSetDocumentationGenerator.php b/vendor/friendsofphp/php-cs-fixer/src/Documentation/RuleSetDocumentationGenerator.php index f74a1a93..c87808c8 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Documentation/RuleSetDocumentationGenerator.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Documentation/RuleSetDocumentationGenerator.php @@ -16,6 +16,7 @@ use PhpCsFixer\Fixer\FixerInterface; use PhpCsFixer\Preg; +use PhpCsFixer\RuleSet\DeprecatedRuleSetDescriptionInterface; use PhpCsFixer\RuleSet\RuleSetDescriptionInterface; use PhpCsFixer\Utils; @@ -32,7 +33,7 @@ public function __construct(DocumentationLocator $locator) } /** - * @param FixerInterface[] $fixers + * @param list $fixers */ public function generateRuleSetsDocumentation(RuleSetDescriptionInterface $definition, array $fixers): string { @@ -46,8 +47,52 @@ public function generateRuleSetsDocumentation(RuleSetDescriptionInterface $defin $titleLine = str_repeat('=', \strlen($title)); $doc = "{$titleLine}\n{$title}\n{$titleLine}\n\n".$definition->getDescription(); + $warnings = []; + if ($definition instanceof DeprecatedRuleSetDescriptionInterface) { + $deprecationDescription = <<<'RST' + + This rule set is deprecated and will be removed in the next major version + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RST; + $alternatives = $definition->getSuccessorsNames(); + + if (0 !== \count($alternatives)) { + $deprecationDescription .= RstUtils::toRst( + sprintf( + "\n\nYou should use %s instead.", + Utils::naturalLanguageJoinWithBackticks($alternatives) + ), + 0 + ); + } else { + $deprecationDescription .= 'No replacement available.'; + } + + $warnings[] = $deprecationDescription; + } + if ($definition->isRisky()) { - $doc .= ' This set contains rules that are risky.'; + $warnings[] = <<<'RST' + + This set contains rules that are risky + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Using this rule set may lead to changes in your code's logic and behaviour. Use it with caution and review changes before incorporating them into your code base. + RST; + } + + if ([] !== $warnings) { + $warningsHeader = 1 === \count($warnings) ? 'Warning' : 'Warnings'; + + $warningsHeaderLine = str_repeat('-', \strlen($warningsHeader)); + $doc .= "\n\n".implode( + "\n", + [ + $warningsHeader, + $warningsHeaderLine, + ...$warnings, + ] + ); } $rules = $definition->getRules(); @@ -96,7 +141,7 @@ public function generateRuleSetsDocumentation(RuleSetDescriptionInterface $defin } /** - * @param array $setDefinitions + * @param array $setDefinitions */ public function generateRuleSetsDocumentationIndex(array $setDefinitions): string { @@ -105,9 +150,21 @@ public function generateRuleSetsDocumentationIndex(array $setDefinitions): strin List of Available Rule sets =========================== RST; - foreach ($setDefinitions as $name => $path) { + + foreach ($setDefinitions as $path => $definition) { $path = substr($path, strrpos($path, '/')); - $documentation .= "\n- `{$name} <.{$path}>`_"; + + $attributes = []; + + if ($definition instanceof DeprecatedRuleSetDescriptionInterface) { + $attributes[] = 'deprecated'; + } + + $attributes = 0 === \count($attributes) + ? '' + : ' *('.implode(', ', $attributes).')*'; + + $documentation .= "\n- `{$definition->getName()} <.{$path}>`_{$attributes}"; } return $documentation."\n"; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Error/ErrorsManager.php b/vendor/friendsofphp/php-cs-fixer/src/Error/ErrorsManager.php index 3d787a3f..d1d9e0cf 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Error/ErrorsManager.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Error/ErrorsManager.php @@ -24,14 +24,14 @@ final class ErrorsManager { /** - * @var Error[] + * @var list */ private array $errors = []; /** * Returns errors reported during linting before fixing. * - * @return Error[] + * @return list */ public function getInvalidErrors(): array { @@ -41,7 +41,7 @@ public function getInvalidErrors(): array /** * Returns errors reported during fixing. * - * @return Error[] + * @return list */ public function getExceptionErrors(): array { @@ -51,7 +51,7 @@ public function getExceptionErrors(): array /** * Returns errors reported during linting after fixing. * - * @return Error[] + * @return list */ public function getLintErrors(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandler.php b/vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandler.php new file mode 100644 index 00000000..003398e4 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandler.php @@ -0,0 +1,58 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer; + +/** + * @author Dariusz Rumiński + * + * @internal + */ +final class ExecutorWithoutErrorHandler +{ + private function __construct() {} + + /** + * @template T + * + * @param callable(): T $callback + * + * @return T + * + * @throws ExecutorWithoutErrorHandlerException + */ + public static function execute(callable $callback) + { + /** @var ?string */ + $error = null; + + set_error_handler(static function (int $errorNumber, string $errorString, string $errorFile, int $errorLine) use (&$error): bool { + $error = $errorString; + + return true; + }); + + try { + $result = $callback(); + } finally { + restore_error_handler(); + } + + if (null !== $error) { + throw new ExecutorWithoutErrorHandlerException($error); + } + + return $result; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandlerException.php b/vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandlerException.php new file mode 100644 index 00000000..750352a2 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/ExecutorWithoutErrorHandlerException.php @@ -0,0 +1,22 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer; + +/** + * @author Dariusz Rumiński + * + * @internal + */ +final class ExecutorWithoutErrorHandlerException extends \RuntimeException {} diff --git a/vendor/friendsofphp/php-cs-fixer/src/FileRemoval.php b/vendor/friendsofphp/php-cs-fixer/src/FileRemoval.php index dce4d924..148a4c5e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/FileRemoval.php +++ b/vendor/friendsofphp/php-cs-fixer/src/FileRemoval.php @@ -47,7 +47,7 @@ public function __destruct() */ public function __sleep(): array { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + throw new \BadMethodCallException('Cannot serialize '.self::class); } /** @@ -58,7 +58,7 @@ public function __sleep(): array */ public function __wakeup(): void { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + throw new \BadMethodCallException('Cannot unserialize '.self::class); } /** diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/AbstractPhpUnitFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/AbstractPhpUnitFixer.php index 9d90aba1..f322f4c5 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/AbstractPhpUnitFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/AbstractPhpUnitFixer.php @@ -18,6 +18,8 @@ use PhpCsFixer\DocBlock\DocBlock; use PhpCsFixer\DocBlock\Line; use PhpCsFixer\Indicator\PhpUnitTestCaseIndicator; +use PhpCsFixer\Tokenizer\Analyzer\AttributeAnalyzer; +use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\WhitespacesAnalyzer; use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Token; @@ -28,7 +30,7 @@ */ abstract class AbstractPhpUnitFixer extends AbstractFixer { - final public function isCandidate(Tokens $tokens): bool + public function isCandidate(Tokens $tokens): bool { return $tokens->isAllTokenKindsFound([T_CLASS, T_STRING]); } @@ -68,16 +70,22 @@ final protected function getDocBlockIndex(Tokens $tokens, int $index): int } /** - * @param array $preventingAnnotations + * @param list $preventingAnnotations + * @param list $preventingAttributes */ - final protected function ensureIsDockBlockWithAnnotation( + final protected function ensureIsDocBlockWithAnnotation( Tokens $tokens, int $index, string $annotation, - array $preventingAnnotations + array $preventingAnnotations, + array $preventingAttributes ): void { $docBlockIndex = $this->getDocBlockIndex($tokens, $index); + if (self::isPreventedByAttribute($tokens, $index, $preventingAttributes)) { + return; + } + if ($this->isPHPDoc($tokens, $docBlockIndex)) { $this->updateDocBlockIfNeeded($tokens, $docBlockIndex, $annotation, $preventingAnnotations); } else { @@ -115,7 +123,7 @@ private function createDocBlock(Tokens $tokens, int $docBlockIndex, string $anno } /** - * @param array $preventingAnnotations + * @param list $preventingAnnotations */ private function updateDocBlockIfNeeded( Tokens $tokens, @@ -137,7 +145,57 @@ private function updateDocBlockIfNeeded( } /** - * @return array + * @param list $preventingAttributes + */ + private static function isPreventedByAttribute(Tokens $tokens, int $index, array $preventingAttributes): bool + { + if ([] === $preventingAttributes) { + return false; + } + + $attributeIndex = $tokens->getPrevMeaningfulToken($index); + if (!$tokens[$attributeIndex]->isGivenKind(CT::T_ATTRIBUTE_CLOSE)) { + return false; + } + $attributeIndex = $tokens->findBlockStart(Tokens::BLOCK_TYPE_ATTRIBUTE, $attributeIndex); + + foreach (AttributeAnalyzer::collect($tokens, $attributeIndex) as $attributeAnalysis) { + foreach ($attributeAnalysis->getAttributes() as $attribute) { + if (\in_array(self::getFullyQualifiedName($tokens, $attribute['name']), $preventingAttributes, true)) { + return true; + } + } + } + + return false; + } + + private static function getFullyQualifiedName(Tokens $tokens, string $name): string + { + $name = strtolower($name); + + $names = []; + foreach ((new NamespaceUsesAnalyzer())->getDeclarationsFromTokens($tokens) as $namespaceUseAnalysis) { + $names[strtolower($namespaceUseAnalysis->getShortName())] = strtolower($namespaceUseAnalysis->getFullName()); + } + + foreach ($names as $shortName => $fullName) { + if ($name === $shortName) { + return $fullName; + } + + if (!str_starts_with($name, $shortName.'\\')) { + continue; + } + + return $fullName.substr($name, \strlen($shortName)); + } + + return $name; + } + + /** + * @return list */ private function addInternalAnnotation(DocBlock $docBlock, Tokens $tokens, int $docBlockIndex, string $annotation): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/BacktickToShellExecFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/BacktickToShellExecFixer.php index 351cdad7..f2197705 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/BacktickToShellExecFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/BacktickToShellExecFixer.php @@ -53,7 +53,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run before EscapeImplicitBackslashesFixer, ExplicitStringVariableFixer, NativeFunctionInvocationFixer, SingleQuoteFixer. + * Must run before EscapeImplicitBackslashesFixer, ExplicitStringVariableFixer, NativeFunctionInvocationFixer, SingleQuoteFixer, StringImplicitBackslashesFixer. */ public function getPriority(): int { @@ -95,9 +95,8 @@ private function fixBackticks(Tokens $tokens, array $backtickTokens): void { // Track indices for final override ksort($backtickTokens); - $openingBacktickIndex = key($backtickTokens); - end($backtickTokens); - $closingBacktickIndex = key($backtickTokens); + $openingBacktickIndex = array_key_first($backtickTokens); + $closingBacktickIndex = array_key_last($backtickTokens); // Strip enclosing backticks array_shift($backtickTokens); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/EregToPregFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/EregToPregFixer.php index c9366294..396658c3 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/EregToPregFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/EregToPregFixer.php @@ -188,6 +188,6 @@ private function getBestDelimiter(string $pattern): string return $a[0] <=> $b[0]; }); - return key($delimiters); + return array_key_first($delimiters); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/MbStrFunctionsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/MbStrFunctionsFixer.php index 6dd62f49..1cbbd874 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/MbStrFunctionsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/MbStrFunctionsFixer.php @@ -69,6 +69,16 @@ public function __construct() { parent::__construct(); + if (\PHP_VERSION_ID >= 8_03_00) { + self::$functionsMap['str_pad'] = ['alternativeName' => 'mb_str_pad', 'argumentCount' => [1, 2, 3, 4]]; + } + + if (\PHP_VERSION_ID >= 8_04_00) { + self::$functionsMap['trim'] = ['alternativeName' => 'mb_trim', 'argumentCount' => [1, 2]]; + self::$functionsMap['ltrim'] = ['alternativeName' => 'mb_ltrim', 'argumentCount' => [1, 2]]; + self::$functionsMap['rtrim'] = ['alternativeName' => 'mb_rtrim', 'argumentCount' => [1, 2]]; + } + $this->functions = array_filter( self::$functionsMap, static fn (array $mapping): bool => (new \ReflectionFunction($mapping['alternativeName']))->isInternal() diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoAliasFunctionsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoAliasFunctionsFixer.php index b56d0c40..2a3d231d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoAliasFunctionsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoAliasFunctionsFixer.php @@ -156,7 +156,7 @@ final class NoAliasFunctionsFixer extends AbstractFixer implements ConfigurableF ]; /** - * @var array|string> stores alias (key) - master (value) functions mapping + * @var array stores alias (key) - master (value) functions mapping */ private array $aliases = []; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoMixedEchoPrintFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoMixedEchoPrintFixer.php index ff5e666c..e8b1af95 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoMixedEchoPrintFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/NoMixedEchoPrintFixer.php @@ -32,26 +32,15 @@ final class NoMixedEchoPrintFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var string + * @var T_ECHO|T_PRINT */ - private $callBack; - - /** - * @var int T_ECHO or T_PRINT - */ - private $candidateTokenType; + private int $candidateTokenType; public function configure(array $configuration): void { parent::configure($configuration); - if ('echo' === $this->configuration['use']) { - $this->candidateTokenType = T_PRINT; - $this->callBack = 'fixPrintToEcho'; - } else { - $this->candidateTokenType = T_ECHO; - $this->callBack = 'fixEchoToPrint'; - } + $this->candidateTokenType = 'echo' === $this->configuration['use'] ? T_PRINT : T_ECHO; } public function getDefinition(): FixerDefinitionInterface @@ -82,10 +71,13 @@ public function isCandidate(Tokens $tokens): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - $callBack = $this->callBack; foreach ($tokens as $index => $token) { if ($token->isGivenKind($this->candidateTokenType)) { - $this->{$callBack}($tokens, $index); + if (T_PRINT === $this->candidateTokenType) { + $this->fixPrintToEcho($tokens, $index); + } else { + $this->fixEchoToPrint($tokens, $index); + } } } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/PowToExponentiationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/PowToExponentiationFixer.php index a56385e6..84e68090 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/PowToExponentiationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/PowToExponentiationFixer.php @@ -97,7 +97,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return array + * @return list */ private function findPowCalls(Tokens $tokens): array { @@ -205,7 +205,7 @@ private function isParenthesisNeeded(Tokens $tokens, int $argumentStartIndex, in } /** - * @return int[] + * @return list */ private function getAllowedKinds(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/SetTypeToCastFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/SetTypeToCastFixer.php index 2c807eb5..2127e33d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/SetTypeToCastFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Alias/SetTypeToCastFixer.php @@ -126,7 +126,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // --- Test type ------------------------------ - $type = strtolower(trim($tokens[$secondArgumentStart]->getContent(), '"\'"')); + $type = strtolower(trim($tokens[$secondArgumentStart]->getContent(), '"\'')); if ('null' !== $type && !isset($map[$type])) { continue; // we don't know how to map diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/ArraySyntaxFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/ArraySyntaxFixer.php index a7b0b20f..ea418f5e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/ArraySyntaxFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/ArraySyntaxFixer.php @@ -34,21 +34,15 @@ final class ArraySyntaxFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var null|int + * @var CT::T_ARRAY_SQUARE_BRACE_OPEN|T_ARRAY */ private $candidateTokenKind; - /** - * @var null|string - */ - private $fixCallback; - public function configure(array $configuration): void { parent::configure($configuration); $this->resolveCandidateTokenKind(); - $this->resolveFixCallback(); } public function getDefinition(): FixerDefinitionInterface @@ -84,11 +78,13 @@ public function isCandidate(Tokens $tokens): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - $callback = $this->fixCallback; - for ($index = $tokens->count() - 1; 0 <= $index; --$index) { if ($tokens[$index]->isGivenKind($this->candidateTokenKind)) { - $this->{$callback}($tokens, $index); + if ('short' === $this->configuration['syntax']) { + $this->fixToShortArraySyntax($tokens, $index); + } else { + $this->fixToLongArraySyntax($tokens, $index); + } } } } @@ -124,11 +120,6 @@ private function fixToShortArraySyntax(Tokens $tokens, int $index): void $tokens->clearTokenAndMergeSurroundingWhitespace($index); } - private function resolveFixCallback(): void - { - $this->fixCallback = sprintf('fixTo%sArraySyntax', ucfirst($this->configuration['syntax'])); - } - private function resolveCandidateTokenKind(): void { $this->candidateTokenKind = 'long' === $this->configuration['syntax'] ? CT::T_ARRAY_SQUARE_BRACE_OPEN : T_ARRAY; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php index a9c7d051..ed4ef90d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/WhitespaceAfterCommaInArrayFixer.php @@ -83,7 +83,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void if (!$tokens[$i + 1]->isWhitespace()) { $tokensToInsert[$i + 1] = new Token([T_WHITESPACE, ' ']); } elseif ( - $this->configuration['ensure_single_space'] + true === $this->configuration['ensure_single_space'] && ' ' !== $tokens[$i + 1]->getContent() && Preg::match('/^\h+$/', $tokens[$i + 1]->getContent()) && (!$tokens[$i + 2]->isComment() || Preg::match('/^\h+$/', $tokens[$i + 3]->getContent())) diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php index 7df614fc..021d1cd1 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ArrayNotation/YieldFromArrayToYieldsFixer.php @@ -118,7 +118,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return iterable> + * @return iterable */ private function getYieldsFromToUnpack(Tokens $tokens): iterable { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php new file mode 100644 index 00000000..5382deb4 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/AttributeNotation/OrderedAttributesFixer.php @@ -0,0 +1,310 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\AttributeNotation; + +use PhpCsFixer\AbstractFixer; +use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException; +use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; +use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\FixerDefinition\VersionSpecification; +use PhpCsFixer\FixerDefinition\VersionSpecificCodeSample; +use PhpCsFixer\Tokenizer\Analyzer\Analysis\AttributeAnalysis; +use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceAnalysis; +use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceUseAnalysis; +use PhpCsFixer\Tokenizer\Analyzer\AttributeAnalyzer; +use PhpCsFixer\Tokenizer\Analyzer\NamespacesAnalyzer; +use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; +use Symfony\Component\OptionsResolver\Options; + +/** + * @author HypeMC + * + * @phpstan-import-type _AttributeItems from AttributeAnalysis + */ +final class OrderedAttributesFixer extends AbstractFixer implements ConfigurableFixerInterface +{ + public const ORDER_ALPHA = 'alpha'; + public const ORDER_CUSTOM = 'custom'; + + private const SUPPORTED_SORT_ALGORITHMS = [ + self::ORDER_ALPHA, + self::ORDER_CUSTOM, + ]; + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'Sorts attributes using the configured sort algorithm.', + [ + new VersionSpecificCodeSample( + <<<'EOL' + self::ORDER_CUSTOM, 'order' => ['A\B\Qux', 'A\B\Bar', 'A\B\Corge']], + ), + ], + ); + } + + /** + * {@inheritdoc} + * + * Must run after FullyQualifiedStrictTypesFixer. + */ + public function getPriority(): int + { + return 0; + } + + public function isCandidate(Tokens $tokens): bool + { + return \defined('T_ATTRIBUTE') && $tokens->isTokenKindFound(T_ATTRIBUTE); + } + + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface + { + $fixerName = $this->getName(); + + return new FixerConfigurationResolver([ + (new FixerOptionBuilder('sort_algorithm', 'How the attributes should be sorted.')) + ->setAllowedValues(self::SUPPORTED_SORT_ALGORITHMS) + ->setDefault(self::ORDER_ALPHA) + ->setNormalizer(static function (Options $options, string $value) use ($fixerName): string { + if (self::ORDER_CUSTOM === $value && [] === $options['order']) { + throw new InvalidFixerConfigurationException( + $fixerName, + 'The custom order strategy requires providing `order` option with a list of attributes\'s FQNs.' + ); + } + + return $value; + }) + ->getOption(), + (new FixerOptionBuilder('order', 'A list of FQCNs of attributes defining the desired order used when custom sorting algorithm is configured.')) + ->setAllowedTypes(['string[]']) + ->setDefault([]) + ->setNormalizer(static function (Options $options, array $value) use ($fixerName): array { + if ($value !== array_unique($value)) { + throw new InvalidFixerConfigurationException($fixerName, 'The list includes attributes that are not unique.'); + } + + return array_flip(array_values( + array_map(static fn (string $attribute): string => ltrim($attribute, '\\'), $value), + )); + }) + ->getOption(), + ]); + } + + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void + { + $index = 0; + + while (null !== $index = $tokens->getNextTokenOfKind($index, [[T_ATTRIBUTE]])) { + /** @var list $elements */ + $elements = array_map(function (AttributeAnalysis $attributeAnalysis) use ($tokens): array { + return [ + 'name' => $this->sortAttributes($tokens, $attributeAnalysis->getStartIndex(), $attributeAnalysis->getAttributes()), + 'start' => $attributeAnalysis->getStartIndex(), + 'end' => $attributeAnalysis->getEndIndex(), + ]; + }, AttributeAnalyzer::collect($tokens, $index)); + + $endIndex = end($elements)['end']; + + try { + if (1 === \count($elements)) { + continue; + } + + $sortedElements = $this->sortElements($elements); + + if ($elements === $sortedElements) { + continue; + } + + $this->sortTokens($tokens, $index, $endIndex, $sortedElements); + } finally { + $index = $endIndex; + } + } + } + + /** + * @param _AttributeItems $attributes + */ + private function sortAttributes(Tokens $tokens, int $index, array $attributes): string + { + if (1 === \count($attributes)) { + return $this->getAttributeName($tokens, $attributes[0]['name'], $attributes[0]['start']); + } + + foreach ($attributes as &$attribute) { + $attribute['name'] = $this->getAttributeName($tokens, $attribute['name'], $attribute['start']); + } + + $sortedElements = $this->sortElements($attributes); + + if ($attributes === $sortedElements) { + return $attributes[0]['name']; + } + + $this->sortTokens($tokens, $index + 1, end($attributes)['end'], $sortedElements, new Token(',')); + + return $sortedElements[0]['name']; + } + + private function getAttributeName(Tokens $tokens, string $name, int $index): string + { + if (self::ORDER_CUSTOM === $this->configuration['sort_algorithm']) { + $name = $this->determineAttributeFullyQualifiedName($tokens, $name, $index); + } + + return ltrim($name, '\\'); + } + + private function determineAttributeFullyQualifiedName(Tokens $tokens, string $name, int $index): string + { + if ('\\' === $name[0]) { + return $name; + } + + if (!$tokens[$index]->isGivenKind([T_STRING, T_NS_SEPARATOR])) { + $index = $tokens->getNextTokenOfKind($index, [[T_STRING], [T_NS_SEPARATOR]]); + } + + [$namespaceAnalysis, $namespaceUseAnalyses] = $this->collectNamespaceAnalysis($tokens, $index); + $namespace = $namespaceAnalysis->getFullName(); + $firstTokenOfName = $tokens[$index]->getContent(); + $namespaceUseAnalysis = $namespaceUseAnalyses[$firstTokenOfName] ?? false; + + if ($namespaceUseAnalysis instanceof NamespaceUseAnalysis) { + $namespace = $namespaceUseAnalysis->getFullName(); + + if ($name === $firstTokenOfName) { + return $namespace; + } + + $name = substr(strstr($name, '\\'), 1); + } + + return $namespace.'\\'.$name; + } + + /** + * @param list $elements + * + * @return list + */ + private function sortElements(array $elements): array + { + usort($elements, function (array $a, array $b): int { + $sortAlgorithm = $this->configuration['sort_algorithm']; + + if (self::ORDER_ALPHA === $sortAlgorithm) { + return $a['name'] <=> $b['name']; + } + + if (self::ORDER_CUSTOM === $sortAlgorithm) { + return + ($this->configuration['order'][$a['name']] ?? PHP_INT_MAX) + <=> + ($this->configuration['order'][$b['name']] ?? PHP_INT_MAX); + } + + throw new \InvalidArgumentException(sprintf('Invalid sort algorithm "%s" provided.', $sortAlgorithm)); + }); + + return $elements; + } + + /** + * @param list $elements + */ + private function sortTokens(Tokens $tokens, int $startIndex, int $endIndex, array $elements, ?Token $delimiter = null): void + { + $replaceTokens = []; + + foreach ($elements as $pos => $element) { + for ($i = $element['start']; $i <= $element['end']; ++$i) { + $replaceTokens[] = clone $tokens[$i]; + } + if (null !== $delimiter && $pos !== \count($elements) - 1) { + $replaceTokens[] = clone $delimiter; + } + } + + $tokens->overrideRange($startIndex, $endIndex, $replaceTokens); + } + + /** + * @return array{NamespaceAnalysis, array} + */ + private function collectNamespaceAnalysis(Tokens $tokens, int $startIndex): array + { + $namespaceAnalysis = (new NamespacesAnalyzer())->getNamespaceAt($tokens, $startIndex); + $namespaceUseAnalyses = (new NamespaceUsesAnalyzer())->getDeclarationsInNamespace($tokens, $namespaceAnalysis); + + $uses = []; + foreach ($namespaceUseAnalyses as $use) { + if (!$use->isClass()) { + continue; + } + + $uses[$use->getShortName()] = $use; + } + + return [$namespaceAnalysis, $uses]; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php index a5b3916b..19a57988 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesFixer.php @@ -51,9 +51,9 @@ final class BracesFixer extends AbstractProxyFixer implements ConfigurableFixerI public const LINE_SAME = 'same'; /** - * @var null|CurlyBracesPositionFixer + * @var null|BracesPositionFixer */ - private $curlyBracesPositionFixer; + private $bracesPositionFixer; /** * @var null|ControlStructureContinuationPositionFixer @@ -152,11 +152,11 @@ public function getSuccessorsNames(): array return array_keys($this->proxyFixers); } - public function configure(array $configuration = null): void + public function configure(array $configuration): void { parent::configure($configuration); - $this->getCurlyBracesPositionFixer()->configure([ + $this->getBracesPositionFixer()->configure([ 'control_structures_opening_brace' => $this->translatePositionOption($this->configuration['position_after_control_structures']), 'functions_opening_brace' => $this->translatePositionOption($this->configuration['position_after_functions_and_oop_constructs']), 'anonymous_functions_opening_brace' => $this->translatePositionOption($this->configuration['position_after_anonymous_constructs']), @@ -217,7 +217,7 @@ protected function createProxyFixers(): array $singleSpaceAroundConstructFixer, new ControlStructureBracesFixer(), $noExtraBlankLinesFixer, - $this->getCurlyBracesPositionFixer(), + $this->getBracesPositionFixer(), $this->getControlStructureContinuationPositionFixer(), new DeclareParenthesesFixer(), new NoMultipleStatementsPerLineFixer(), @@ -225,13 +225,13 @@ protected function createProxyFixers(): array ]; } - private function getCurlyBracesPositionFixer(): CurlyBracesPositionFixer + private function getBracesPositionFixer(): BracesPositionFixer { - if (null === $this->curlyBracesPositionFixer) { - $this->curlyBracesPositionFixer = new CurlyBracesPositionFixer(); + if (null === $this->bracesPositionFixer) { + $this->bracesPositionFixer = new BracesPositionFixer(); } - return $this->curlyBracesPositionFixer; + return $this->bracesPositionFixer; } private function getControlStructureContinuationPositionFixer(): ControlStructureContinuationPositionFixer @@ -246,7 +246,7 @@ private function getControlStructureContinuationPositionFixer(): ControlStructur private function translatePositionOption(string $option): string { return self::LINE_NEXT === $option - ? CurlyBracesPositionFixer::NEXT_LINE_UNLESS_NEWLINE_AT_SIGNATURE_END - : CurlyBracesPositionFixer::SAME_LINE; + ? BracesPositionFixer::NEXT_LINE_UNLESS_NEWLINE_AT_SIGNATURE_END + : BracesPositionFixer::SAME_LINE; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php index 4812308a..710448a4 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/BracesPositionFixer.php @@ -165,7 +165,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $openBraceIndex = $tokens->getNextTokenOfKind($index, ['{']); if ($tokensAnalyzer->isAnonymousClass($index)) { - $allowSingleLineIfEmpty = $this->configuration['allow_single_line_empty_anonymous_classes']; + $allowSingleLineIfEmpty = true === $this->configuration['allow_single_line_empty_anonymous_classes']; $positionOption = 'anonymous_classes_opening_brace'; } else { $positionOption = 'classes_opening_brace'; @@ -178,7 +178,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } if ($tokensAnalyzer->isLambda($index)) { - $allowSingleLine = $this->configuration['allow_single_line_anonymous_functions']; + $allowSingleLine = true === $this->configuration['allow_single_line_anonymous_functions']; $positionOption = 'anonymous_functions_opening_brace'; } else { $positionOption = 'functions_opening_brace'; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoTrailingCommaInSinglelineFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoTrailingCommaInSinglelineFixer.php index 610299b3..2c8e0857 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoTrailingCommaInSinglelineFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NoTrailingCommaInSinglelineFixer.php @@ -95,7 +95,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void private function shouldBeCleared(Tokens $tokens, int $openIndex): bool { - /** @var string[] $elements */ + /** @var list $elements */ $elements = $this->configuration['elements']; if ($tokens[$openIndex]->isGivenKind(CT::T_ARRAY_SQUARE_BRACE_OPEN)) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NonPrintableCharacterFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NonPrintableCharacterFixer.php index 318c9fa6..cb885d14 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NonPrintableCharacterFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NonPrintableCharacterFixer.php @@ -34,12 +34,12 @@ final class NonPrintableCharacterFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var array + * @var array */ private array $symbolsReplace; /** - * @var int[] + * @var list */ private static array $tokens = [ T_STRING_VARNAME, @@ -116,7 +116,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $content = $token->getContent(); if ( - $this->configuration['use_escape_sequences_in_strings'] + true === $this->configuration['use_escape_sequences_in_strings'] && $token->isGivenKind([T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE]) ) { if (!Preg::match('/'.implode('|', array_keys($escapeSequences)).'/', $content)) { @@ -144,7 +144,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } if ($stringTypeChanged) { - $content = Preg::replace('/(\\\\{1,2})/', '\\\\\\\\', $content); + $content = Preg::replace('/(\\\{1,2})/', '\\\\\\\\', $content); $content = str_replace('$', '\$', $content); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NumericLiteralSeparatorFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NumericLiteralSeparatorFixer.php new file mode 100644 index 00000000..79d52e62 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/NumericLiteralSeparatorFixer.php @@ -0,0 +1,217 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\Basic; + +use PhpCsFixer\AbstractFixer; +use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; +use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * Let's you add underscores to numeric literals. + * + * Inspired by: + * - {@link https://github.com/kubawerlos/php-cs-fixer-custom-fixers/blob/main/src/Fixer/NumericLiteralSeparatorFixer.php} + * - {@link https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/rules/numeric-separators-style.js} + * + * @author Marvin Heilemann + * @author Greg Korba + */ +final class NumericLiteralSeparatorFixer extends AbstractFixer implements ConfigurableFixerInterface +{ + public const STRATEGY_USE_SEPARATOR = 'use_separator'; + public const STRATEGY_NO_SEPARATOR = 'no_separator'; + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'Adds separators to numeric literals of any kind.', + [ + new CodeSample( + <<<'PHP' + self::STRATEGY_NO_SEPARATOR], + ), + new CodeSample( + <<<'PHP' + self::STRATEGY_USE_SEPARATOR], + ), + new CodeSample( + " true] + ), + ] + ); + } + + public function isCandidate(Tokens $tokens): bool + { + return $tokens->isAnyTokenKindsFound([T_DNUMBER, T_LNUMBER]); + } + + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface + { + return new FixerConfigurationResolver([ + (new FixerOptionBuilder( + 'override_existing', + 'Whether literals already containing underscores should be reformatted.' + )) + ->setAllowedTypes(['bool']) + ->setDefault(false) + ->getOption(), + (new FixerOptionBuilder( + 'strategy', + 'Whether numeric literal should be separated by underscores or not.' + )) + ->setAllowedValues([self::STRATEGY_USE_SEPARATOR, self::STRATEGY_NO_SEPARATOR]) + ->setDefault(self::STRATEGY_USE_SEPARATOR) + ->getOption(), + ]); + } + + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void + { + foreach ($tokens as $index => $token) { + if (!$token->isGivenKind([T_DNUMBER, T_LNUMBER])) { + continue; + } + + $content = $token->getContent(); + + $newContent = $this->formatValue($content); + + if ($content === $newContent) { + // Skip Token override if its the same content, like when it + // already got a valid literal separator structure. + continue; + } + + $tokens[$index] = new Token([$token->getId(), $newContent]); + } + } + + private function formatValue(string $value): string + { + if (self::STRATEGY_NO_SEPARATOR === $this->configuration['strategy']) { + return str_contains($value, '_') ? str_replace('_', '', $value) : $value; + } + + if (true === $this->configuration['override_existing']) { + $value = str_replace('_', '', $value); + } elseif (str_contains($value, '_')) { + // Keep already underscored literals untouched. + return $value; + } + + $lowerValue = strtolower($value); + + if (str_starts_with($lowerValue, '0b')) { + // Binary + return $this->insertEveryRight($value, 8, 2); + } + + if (str_starts_with($lowerValue, '0x')) { + // Hexadecimal + return $this->insertEveryRight($value, 2, 2); + } + + if (str_starts_with($lowerValue, '0o')) { + // Octal + return $this->insertEveryRight($value, 3, 2); + } + if (str_starts_with($lowerValue, '0') && !str_contains($lowerValue, '.')) { + // Octal notation prior PHP 8.1 but still valid + return $this->insertEveryRight($value, 3, 1); + } + + // All other types + + /** If its a negative value we need an offset */ + $negativeOffset = static fn ($v) => str_contains($v, '-') ? 1 : 0; + + Preg::matchAll('/([0-9-_]+)?((\.)([0-9_]*))?((e)([0-9-_]+))?/i', $value, $result); + + $integer = $result[1][0]; + $joinedValue = $this->insertEveryRight($integer, 3, $negativeOffset($integer)); + + $dot = $result[3][0]; + if ('' !== $dot) { + $integer = $result[4][0]; + $decimal = $this->insertEveryLeft($integer, 3, $negativeOffset($integer)); + $joinedValue = $joinedValue.$dot.$decimal; + } + + $tim = $result[6][0]; + if ('' !== $tim) { + $integer = $result[7][0]; + $times = $this->insertEveryRight($integer, 3, $negativeOffset($integer)); + $joinedValue = $joinedValue.$tim.$times; + } + + return $joinedValue; + } + + private function insertEveryRight(string $value, int $length, int $offset = 0): string + { + $position = $length * -1; + while ($position > -(\strlen($value) - $offset)) { + $value = substr_replace($value, '_', $position, 0); + $position -= $length + 1; + } + + return $value; + } + + private function insertEveryLeft(string $value, int $length, int $offset = 0): string + { + $position = $length; + while ($position < \strlen($value)) { + $value = substr_replace($value, '_', $position, $offset); + $position += $length + 1; + } + + return $value; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/PsrAutoloadingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/PsrAutoloadingFixer.php index 2f31f540..db42b697 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/PsrAutoloadingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Basic/PsrAutoloadingFixer.php @@ -127,7 +127,7 @@ public function supports(\SplFileInfo $file): bool } // ignore stubs/fixtures, since they typically contain invalid files for various reasons - return !Preg::match('{[/\\\\](stub|fixture)s?[/\\\\]}i', $file->getRealPath()); + return !Preg::match('{[/\\\](stub|fixture)s?[/\\\]}i', $file->getRealPath()); } protected function createConfigurationDefinition(): FixerConfigurationResolverInterface diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ClassReferenceNameCasingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ClassReferenceNameCasingFixer.php index 83b0f979..20b951d1 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ClassReferenceNameCasingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ClassReferenceNameCasingFixer.php @@ -84,6 +84,10 @@ private function getClassReference(Tokens $tokens, NamespaceAnalysis $namespace) T_TRAIT, ]; + if (\defined('T_NULLSAFE_OBJECT_OPERATOR')) { // @TODO: drop condition when PHP 8.0+ is required + $notBeforeKinds[] = T_NULLSAFE_OBJECT_OPERATOR; + } + if (\defined('T_ENUM')) { // @TODO: drop condition when PHP 8.1+ is required $notBeforeKinds[] = T_ENUM; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ConstantCaseFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ConstantCaseFixer.php index 14501aaf..ab3738f0 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ConstantCaseFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/ConstantCaseFixer.php @@ -88,9 +88,12 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } + $nextIndex = $tokens->getNextMeaningfulToken($index); + if ( $this->isNeighbourAccepted($tokens, $tokens->getPrevMeaningfulToken($index)) - && $this->isNeighbourAccepted($tokens, $tokens->getNextMeaningfulToken($index)) + && $this->isNeighbourAccepted($tokens, $nextIndex) + && !$tokens[$nextIndex]->equals('=') && !$this->isEnumCaseName($tokens, $index) ) { $tokens[$index] = new Token([$token->getId(), $fixFunction($token->getContent())]); @@ -106,7 +109,6 @@ private function isNeighbourAccepted(Tokens $tokens, int $index): bool $forbiddenTokens = [ T_AS, T_CLASS, - T_CONST, T_EXTENDS, T_IMPLEMENTS, T_INSTANCEOF, diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseKeywordsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseKeywordsFixer.php index 120e4cde..f11b9988 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseKeywordsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseKeywordsFixer.php @@ -29,7 +29,7 @@ final class LowercaseKeywordsFixer extends AbstractFixer { /** - * @var int[] + * @var list */ private static array $excludedTokens = [T_HALT_COMPILER]; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseStaticReferenceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseStaticReferenceFixer.php index 325264b2..7615b296 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseStaticReferenceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/LowercaseStaticReferenceFixer.php @@ -84,7 +84,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } $prevIndex = $tokens->getPrevMeaningfulToken($index); - if ($tokens[$prevIndex]->isGivenKind([T_CONST, T_DOUBLE_COLON, T_FUNCTION, T_NAMESPACE, T_NS_SEPARATOR]) || $tokens[$prevIndex]->isObjectOperator()) { + if ($tokens[$prevIndex]->isGivenKind([T_CONST, T_DOUBLE_COLON, T_FUNCTION, T_NAMESPACE, T_NS_SEPARATOR, T_STATIC, T_STRING, CT::T_ARRAY_TYPEHINT, CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE]) || $tokens[$prevIndex]->isObjectOperator()) { continue; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicConstantCasingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicConstantCasingFixer.php index f4902b77..b8de332e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicConstantCasingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicConstantCasingFixer.php @@ -77,7 +77,7 @@ private function getMagicConstants(): array } /** - * @return array + * @return list */ private function getMagicConstantTokens(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicMethodCasingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicMethodCasingFixer.php index 4a203906..544d2cbb 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicMethodCasingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/MagicMethodCasingFixer.php @@ -24,7 +24,7 @@ final class MagicMethodCasingFixer extends AbstractFixer { /** - * @var array + * @var array */ private static array $magicNames = [ '__call' => '__call', diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/NativeTypeDeclarationCasingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/NativeTypeDeclarationCasingFixer.php index c0e8aa32..e46f10df 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/NativeTypeDeclarationCasingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Casing/NativeTypeDeclarationCasingFixer.php @@ -119,15 +119,15 @@ final class NativeTypeDeclarationCasingFixer extends AbstractFixer private FunctionsAnalyzer $functionsAnalyzer; /** - * @var list> + * @var list */ - private array $propertyTypeModifiers; + private array $beforePropertyTypeTokens; public function __construct() { parent::__construct(); - $this->propertyTypeModifiers = [[T_PRIVATE], [T_PROTECTED], [T_PUBLIC]]; + $this->beforePropertyTypeTokens = ['{', ';', [T_PRIVATE], [T_PROTECTED], [T_PUBLIC], [T_VAR]]; $this->functionTypeHints = [ 'array' => true, @@ -152,7 +152,7 @@ public function __construct() if (\PHP_VERSION_ID >= 8_01_00) { $this->functionTypeHints['never'] = true; - $this->propertyTypeModifiers[] = [T_READONLY]; + $this->beforePropertyTypeTokens[] = [T_READONLY]; } if (\PHP_VERSION_ID >= 8_02_00) { @@ -296,7 +296,7 @@ private function getConstNameIndex(Tokens $tokens, int $index): int private function getNativeTypeHintCandidatesForProperty(Tokens $tokens, int $index): iterable { $propertyNameIndex = $index; - $index = $tokens->getPrevTokenOfKind($index, $this->propertyTypeModifiers); + $index = $tokens->getPrevTokenOfKind($index, $this->beforePropertyTypeTokens); $index = $this->getFirstIndexOfType($tokens, $index); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php index aa0fe130..a0c4f720 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassAttributesSeparationFixer.php @@ -37,6 +37,14 @@ * Make sure there is one blank line above and below class elements. * * The exception is when an element is the first or last item in a 'classy'. + * + * @phpstan-type _Class array{ + * index: int, + * open: int, + * close: int, + * elements: non-empty-list<_Element> + * } + * @phpstan-type _Element array{token: Token, type: string, index: int, start?: int, end?: int} */ final class ClassAttributesSeparationFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { @@ -239,12 +247,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn * Deals with comments, PHPDocs and spaces above the element with respect to the position of the * element within the class, interface or trait. * - * @param array{ - * index: int, - * open: int, - * close: int, - * elements: non-empty-list - * } $class + * @param _Class $class */ private function fixSpaceAboveClassElement(Tokens $tokens, array $class, int $elementIndex): void { @@ -315,6 +318,9 @@ private function fixSpaceAboveClassElement(Tokens $tokens, array $class, int $el $this->correctLineBreaks($tokens, $nonWhiteAbove, $element['start'], $this->determineRequiredLineCount($tokens, $class, $elementIndex)); } + /** + * @param _Class $class + */ private function determineRequiredLineCount(Tokens $tokens, array $class, int $elementIndex): int { $type = $class['elements'][$elementIndex]['type']; @@ -350,12 +356,7 @@ private function determineRequiredLineCount(Tokens $tokens, array $class, int $e } /** - * @param array{ - * index: int, - * open: int, - * close: int, - * elements: non-empty-list - * } $class + * @param _Class $class */ private function fixSpaceBelowClassElement(Tokens $tokens, array $class): void { @@ -458,12 +459,7 @@ private function findCommentBlockStart(Tokens $tokens, int $start, int $elementA /** * @TODO Introduce proper DTO instead of an array * - * @return \Generator - * }> + * @return \Generator<_Class> */ private function getElementsByClass(Tokens $tokens): \Generator { @@ -509,6 +505,12 @@ private function getElementsByClass(Tokens $tokens): \Generator } } + /** + * including trailing single line comments if belonging to the class element. + * + * @param _Class $class + * @param _Element $element + */ private function getFirstTokenIndexOfClassElement(Tokens $tokens, array $class, array $element): int { $modifierTypes = [T_PRIVATE, T_PROTECTED, T_PUBLIC, T_ABSTRACT, T_FINAL, T_STATIC, T_STRING, T_NS_SEPARATOR, T_VAR, CT::T_NULLABLE_TYPE, CT::T_ARRAY_TYPEHINT, CT::T_TYPE_ALTERNATION, CT::T_TYPE_INTERSECTION, CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_OPEN, CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE]; @@ -532,7 +534,12 @@ private function getFirstTokenIndexOfClassElement(Tokens $tokens, array $class, return $firstElementAttributeIndex; } - // including trailing single line comments if belonging to the class element + /** + * including trailing single line comments if belonging to the class element. + * + * @param _Class $class + * @param _Element $element + */ private function getLastTokenIndexOfClassElement(Tokens $tokens, array $class, array $element, TokensAnalyzer $tokensAnalyzer): int { // find last token of the element diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassDefinitionFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassDefinitionFixer.php index 6be1745b..1ca054e5 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassDefinitionFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/ClassDefinitionFixer.php @@ -23,12 +23,16 @@ use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; use PhpCsFixer\Tokenizer\TokensAnalyzer; /** * Fixer for part of the rules defined in PSR2 ¶4.1 Extends and Implements and PSR12 ¶8. Anonymous Classes. + * + * @phpstan-type _ClassExtendsInfo array{start: int, numberOfExtends: int, multiLine: bool} + * @phpstan-type _ClassImplementsInfo array{start: int, numberOfImplements: int, multiLine: bool} */ final class ClassDefinitionFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { @@ -189,7 +193,7 @@ private function fixClassyDefinition(Tokens $tokens, int $classyIndex): void $end = $tokens->getPrevNonWhitespace($classDefInfo['open']); } - if ($classDefInfo['anonymousClass'] && !$this->configuration['inline_constructor_arguments']) { + if ($classDefInfo['anonymousClass'] && false === $this->configuration['inline_constructor_arguments']) { if (!$tokens[$end]->equals(')')) { // anonymous class with `extends` and/or `implements` $start = $tokens->getPrevMeaningfulToken($end); $this->makeClassyDefinitionSingleLine($tokens, $start, $end); @@ -207,6 +211,11 @@ private function fixClassyDefinition(Tokens $tokens, int $classyIndex): void $this->sortClassModifiers($tokens, $classDefInfo); } + /** + * @param _ClassExtendsInfo $classExtendsInfo + * + * @return _ClassExtendsInfo + */ private function fixClassyDefinitionExtends(Tokens $tokens, int $classOpenIndex, array $classExtendsInfo): array { $endIndex = $tokens->getPrevNonWhitespace($classOpenIndex); @@ -225,6 +234,11 @@ private function fixClassyDefinitionExtends(Tokens $tokens, int $classOpenIndex, return $classExtendsInfo; } + /** + * @param _ClassImplementsInfo $classImplementsInfo + * + * @return _ClassImplementsInfo + */ private function fixClassyDefinitionImplements(Tokens $tokens, int $classOpenIndex, array $classImplementsInfo): array { $endIndex = $tokens->getPrevNonWhitespace($classOpenIndex); @@ -243,6 +257,19 @@ private function fixClassyDefinitionImplements(Tokens $tokens, int $classOpenInd return $classImplementsInfo; } + /** + * @param array{ + * start: int, + * classy: int, + * open: int, + * extends: false|_ClassExtendsInfo, + * implements: false|_ClassImplementsInfo, + * anonymousClass: bool, + * final: false|int, + * abstract: false|int, + * readonly: false|int, + * } $classDefInfo + */ private function fixClassyDefinitionOpenSpacing(Tokens $tokens, array $classDefInfo): int { if ($classDefInfo['anonymousClass']) { @@ -281,8 +308,8 @@ private function fixClassyDefinitionOpenSpacing(Tokens $tokens, array $classDefI * start: int, * classy: int, * open: int, - * extends: false|array{start: int, numberOfExtends: int, multiLine: bool}, - * implements: false|array{start: int, numberOfImplements: int, multiLine: bool}, + * extends: false|_ClassExtendsInfo, + * implements: false|_ClassImplementsInfo, * anonymousClass: bool, * final: false|int, * abstract: false|int, @@ -306,11 +333,11 @@ private function getClassyDefinitionInfo(Tokens $tokens, int $classyIndex): arra if (!$tokens[$classyIndex]->isGivenKind(T_TRAIT)) { $extends = $tokens->findGivenKind(T_EXTENDS, $classyIndex, $openIndex); - $def['extends'] = [] !== $extends ? $this->getClassyInheritanceInfo($tokens, key($extends), 'numberOfExtends') : false; + $def['extends'] = [] !== $extends ? $this->getClassyInheritanceInfo($tokens, array_key_first($extends), 'numberOfExtends') : false; if (!$tokens[$classyIndex]->isGivenKind(T_INTERFACE)) { $implements = $tokens->findGivenKind(T_IMPLEMENTS, $classyIndex, $openIndex); - $def['implements'] = [] !== $implements ? $this->getClassyInheritanceInfo($tokens, key($implements), 'numberOfImplements') : false; + $def['implements'] = [] !== $implements ? $this->getClassyInheritanceInfo($tokens, array_key_first($implements), 'numberOfImplements') : false; $def['anonymousClass'] = $tokensAnalyzer->isAnonymousClass($classyIndex); } } @@ -336,6 +363,9 @@ private function getClassyDefinitionInfo(Tokens $tokens, int $classyIndex): arra return $def; } + /** + * @return array|array{start: int, multiLine: bool} + */ private function getClassyInheritanceInfo(Tokens $tokens, int $startIndex, string $label): array { $implementsInfo = ['start' => $startIndex, $label => 1, 'multiLine' => false]; @@ -362,15 +392,37 @@ private function makeClassyDefinitionSingleLine(Tokens $tokens, int $startIndex, { for ($i = $endIndex; $i >= $startIndex; --$i) { if ($tokens[$i]->isWhitespace()) { - if ($tokens[$i - 1]->isComment() || $tokens[$i + 1]->isComment()) { + if (str_contains($tokens[$i]->getContent(), "\n")) { + if (\defined('T_ATTRIBUTE')) { // @TODO: drop condition and else when PHP 8.0+ is required + if ($tokens[$i - 1]->isGivenKind(CT::T_ATTRIBUTE_CLOSE) || $tokens[$i + 1]->isGivenKind(T_ATTRIBUTE)) { + continue; + } + } else { + if (($tokens[$i - 1]->isComment() && str_ends_with($tokens[$i - 1]->getContent(), ']')) + || ($tokens[$i + 1]->isComment() && str_starts_with($tokens[$i + 1]->getContent(), '#[')) + ) { + continue; + } + } + + if ($tokens[$i - 1]->isGivenKind(T_DOC_COMMENT) || $tokens[$i + 1]->isGivenKind(T_DOC_COMMENT)) { + continue; + } + } + + if ($tokens[$i - 1]->isComment()) { $content = $tokens[$i - 1]->getContent(); + if (!str_starts_with($content, '//') && !str_starts_with($content, '#')) { + $tokens[$i] = new Token([T_WHITESPACE, ' ']); + } - if (!('#' === $content || str_starts_with($content, '//'))) { - $content = $tokens[$i + 1]->getContent(); + continue; + } - if (!('#' === $content || str_starts_with($content, '//'))) { - $tokens[$i] = new Token([T_WHITESPACE, ' ']); - } + if ($tokens[$i + 1]->isComment()) { + $content = $tokens[$i + 1]->getContent(); + if (!str_starts_with($content, '//')) { + $tokens[$i] = new Token([T_WHITESPACE, ' ']); } continue; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/FinalInternalClassFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/FinalInternalClassFixer.php index 4764dcbc..cfd45f02 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/FinalInternalClassFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/FinalInternalClassFixer.php @@ -58,7 +58,7 @@ public function __construct() { parent::__construct(); - $this->checkAttributes = \PHP_VERSION_ID >= 80000; + $this->checkAttributes = \PHP_VERSION_ID >= 8_00_00; } public function configure(array $configuration): void @@ -249,7 +249,7 @@ private function isClassCandidate(TokensAnalyzer $tokensAnalyzer, Tokens $tokens } return \in_array(true, $decisions, true) - || ([] === $decisions && $this->configuration['consider_absent_docblock_as_internal_class']); + || ([] === $decisions && true === $this->configuration['consider_absent_docblock_as_internal_class']); } private function isClassCandidateBasedOnPhpDoc(Tokens $tokens, int $index): ?bool diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/NoPhp4ConstructorFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/NoPhp4ConstructorFixer.php index be59a15e..6547cc62 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/NoPhp4ConstructorFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/NoPhp4ConstructorFixer.php @@ -290,7 +290,7 @@ private function fixInfiniteRecursion(Tokens $tokens, int $start, int $end): voi * @param int $startIndex function/method start index * @param int $bodyIndex function/method body index * - * @return array an array containing the sequence and case sensitiveness [ 0 => $seq, 1 => $case ] + * @return array{list>, array{3: false}} */ private function getWrapperMethodSequence(Tokens $tokens, string $method, int $startIndex, int $bodyIndex): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedClassElementsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedClassElementsFixer.php index 4337889c..bd352d26 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedClassElementsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedClassElementsFixer.php @@ -25,9 +25,21 @@ use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; +use PhpCsFixer\Utils; /** * @author Gregor Harlan + * + * @phpstan-type _ClassElement array{ + * start: int, + * visibility: string, + * abstract: bool, + * static: bool, + * readonly: bool, + * type: string, + * name: string, + * end: int, + * } */ final class OrderedClassElementsFixer extends AbstractFixer implements ConfigurableFixerInterface { @@ -103,10 +115,10 @@ public function configure(array $configuration): void parent::configure($configuration); $this->typePosition = []; - $pos = 0; + $position = 0; foreach ($this->configuration['order'] as $type) { - $this->typePosition[$type] = $pos++; + $this->typePosition[$type] = $position++; } foreach (self::$typeHierarchy as $type => $parents) { @@ -320,16 +332,7 @@ static function (array $values) use ($builtIns): bool { } /** - * @return list + * @return list<_ClassElement> */ private function getElements(Tokens $tokens, int $startIndex): array { @@ -407,7 +410,7 @@ private function getElements(Tokens $tokens, int $startIndex): array } /** - * @return array|string type or array of type and name + * @return list|string type or array of type and name */ private function detectElementType(Tokens $tokens, int $index) { @@ -475,17 +478,9 @@ private function findElementEnd(Tokens $tokens, int $index): int } /** - * @return list + * @param list<_ClassElement> $elements + * + * @return list<_ClassElement> */ private function sortElements(array $elements): array { @@ -502,24 +497,22 @@ private function sortElements(array $elements): array 'doteardown' => 10, ]; - foreach ($elements as &$element) { + $getPositionType = function (array $element) use ($phpunitPositions): int { $type = $element['type']; if (\in_array($type, ['method', 'magic', 'phpunit'], true) && isset($this->typePosition["method:{$element['name']}"])) { - $element['position'] = $this->typePosition["method:{$element['name']}"]; - - continue; + return $this->typePosition["method:{$element['name']}"]; } if (\array_key_exists($type, self::$specialTypes)) { if (isset($this->typePosition[$type])) { - $element['position'] = $this->typePosition[$type]; + $position = $this->typePosition[$type]; if ('phpunit' === $type) { - $element['position'] += $phpunitPositions[$element['name']]; + $position += $phpunitPositions[$element['name']]; } - continue; + return $position; } $type = 'method'; @@ -541,51 +534,34 @@ private function sortElements(array $elements): array } } - $element['position'] = $this->typePosition[$type]; - } - - unset($element); - - usort($elements, function (array $a, array $b): int { - if ($a['position'] === $b['position']) { - return $this->sortGroupElements($a, $b); - } - - return $a['position'] <=> $b['position']; - }); - - return $elements; + return $this->typePosition[$type]; + }; + + return Utils::stableSort( + $elements, + /** + * @return array{element: _ClassElement, position: int} + */ + static fn (array $element): array => ['element' => $element, 'position' => $getPositionType($element)], + /** + * @param array{element: _ClassElement, position: int} $a + * @param array{element: _ClassElement, position: int} $b + * + * @return -1|0|1 + */ + fn (array $a, array $b): int => ($a['position'] === $b['position']) ? $this->sortGroupElements($a['element'], $b['element']) : $a['position'] <=> $b['position'], + ); } /** - * @param array{ - * start: int, - * visibility: string, - * abstract: bool, - * static: bool, - * readonly: bool, - * type: string, - * name: string, - * end: int, - * position: int, - * } $a - * @param array{ - * start: int, - * visibility: string, - * abstract: bool, - * static: bool, - * readonly: bool, - * type: string, - * name: string, - * end: int, - * position: int, - * } $b + * @param _ClassElement $a + * @param _ClassElement $b */ private function sortGroupElements(array $a, array $b): int { if (self::SORT_ALPHA === $this->configuration['sort_algorithm']) { - return $this->configuration['case_sensitive'] - ? strcmp($a['name'], $b['name']) + return true === $this->configuration['case_sensitive'] + ? $a['name'] <=> $b['name'] : strcasecmp($a['name'], $b['name']); } @@ -593,17 +569,7 @@ private function sortGroupElements(array $a, array $b): int } /** - * @param list $elements + * @param list<_ClassElement> $elements */ private function sortTokens(Tokens $tokens, int $startIndex, int $endIndex, array $elements): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedInterfacesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedInterfacesFixer.php index 87647397..e5179425 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedInterfacesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedInterfacesFixer.php @@ -51,7 +51,7 @@ final class OrderedInterfacesFixer extends AbstractFixer implements Configurable /** * Array of supported directions in configuration. * - * @var string[] + * @var list */ private const SUPPORTED_DIRECTION_OPTIONS = [ self::DIRECTION_ASCEND, @@ -61,7 +61,7 @@ final class OrderedInterfacesFixer extends AbstractFixer implements Configurable /** * Array of supported orders in configuration. * - * @var string[] + * @var list */ private const SUPPORTED_ORDER_OPTIONS = [ self::ORDER_ALPHA, @@ -108,6 +108,16 @@ public function getDefinition(): FixerDefinitionInterface ); } + /** + * {@inheritdoc} + * + * Must run after FullyQualifiedStrictTypesFixer. + */ + public function getPriority(): int + { + return 0; + } + public function isCandidate(Tokens $tokens): bool { return $tokens->isTokenKindFound(T_IMPLEMENTS) @@ -132,7 +142,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } $implementsStart = $index + 1; - $implementsEnd = $tokens->getPrevNonWhitespace($tokens->getNextTokenOfKind($implementsStart, ['{'])); + $implementsEnd = $tokens->getPrevMeaningfulToken($tokens->getNextTokenOfKind($implementsStart, ['{'])); $interfaces = $this->getInterfaces($tokens, $implementsStart, $implementsEnd); @@ -141,7 +151,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } foreach ($interfaces as $interfaceIndex => $interface) { - $interfaceTokens = Tokens::fromArray($interface, false); + $interfaceTokens = Tokens::fromArray($interface); $normalized = ''; $actualInterfaceIndex = $interfaceTokens->getNextMeaningfulToken(-1); @@ -167,8 +177,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $score = self::ORDER_LENGTH === $this->configuration[self::OPTION_ORDER] ? \strlen($first['normalized']) - \strlen($second['normalized']) : ( - $this->configuration['case_sensitive'] - ? strcmp($first['normalized'], $second['normalized']) + true === $this->configuration['case_sensitive'] + ? $first['normalized'] <=> $second['normalized'] : strcasecmp($first['normalized'], $second['normalized']) ); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTraitsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTraitsFixer.php index a46689b3..417eb126 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTraitsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTraitsFixer.php @@ -185,8 +185,8 @@ private function sort(Tokens $tokens, array $elements): void $sortedElements = $elements; uasort( $sortedElements, - fn (Tokens $useA, Tokens $useB): int => $this->configuration['case_sensitive'] - ? strcmp($toTraitName($useA), $toTraitName($useB)) + fn (Tokens $useA, Tokens $useB): int => true === $this->configuration['case_sensitive'] + ? $toTraitName($useA) <=> $toTraitName($useB) : strcasecmp($toTraitName($useA), $toTraitName($useB)) ); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTypesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTypesFixer.php index f1fe0bae..df89754a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTypesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/OrderedTypesFixer.php @@ -74,7 +74,7 @@ public function bar(null|string|int $foo): string|int; public function foo(\Stringable&\Countable $obj): int; } ', - new VersionSpecification(80100), + new VersionSpecification(8_01_00), ['null_adjustment' => 'always_last'] ), new VersionSpecificCodeSample( @@ -84,7 +84,7 @@ interface Bar public function bar(null|string|int $foo): string|int; } ', - new VersionSpecification(80000), + new VersionSpecification(8_00_00), [ 'sort_algorithm' => 'none', 'null_adjustment' => 'always_last', @@ -304,11 +304,11 @@ private function isTypeSortable(TypeAnalysis $type): bool } /** - * @return array{0: array, 1: string} + * @return array{0: list|string>, 1: string} */ private function collectDisjunctiveNormalFormTypes(string $type): array { - $types = array_map(static function ($subType) { + $types = array_map(static function (string $subType) { if (str_starts_with($subType, '(')) { return explode('&', trim($subType, '()')); } @@ -320,7 +320,7 @@ private function collectDisjunctiveNormalFormTypes(string $type): array } /** - * @return array{0: string[], 1: string} + * @return array{0: list, 1: string} */ private function collectUnionOrIntersectionTypes(string $type): array { @@ -336,13 +336,13 @@ private function collectUnionOrIntersectionTypes(string $type): array } /** - * @param array $types + * @param list|string> $types * - * @return array + * @return ($types is list ? list : list>) */ private function runTypesThroughSortingAlgorithm(array $types): array { - $normalizeType = static fn (string $type): string => Preg::replace('/^\\\\?/', '', $type); + $normalizeType = static fn (string $type): string => Preg::replace('/^\\\?/', '', $type); usort($types, function ($a, $b) use ($normalizeType): int { if (\is_array($a)) { @@ -369,7 +369,7 @@ private function runTypesThroughSortingAlgorithm(array $types): array } if ('alpha' === $this->configuration['sort_algorithm']) { - return $this->configuration['case_sensitive'] ? strcmp($a, $b) : strcasecmp($a, $b); + return true === $this->configuration['case_sensitive'] ? $a <=> $b : strcasecmp($a, $b); } return 0; @@ -379,9 +379,9 @@ private function runTypesThroughSortingAlgorithm(array $types): array } /** - * @param array $types + * @param list|string> $types * - * @return array + * @return list */ private function createTypeDeclarationTokens(array $types, string $glue, bool $isDisjunctive = false): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SelfAccessorFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SelfAccessorFixer.php index 1ad573c9..7150b6bb 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SelfAccessorFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SelfAccessorFixer.php @@ -184,7 +184,7 @@ private function getClassStart(Tokens $tokens, int $index, string $namespace): ? { $namespace = ('' !== $namespace ? '\\'.$namespace : '').'\\'; - foreach (array_reverse(Preg::split('/(\\\\)/', $namespace, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)) as $piece) { + foreach (array_reverse(Preg::split('/(\\\)/', $namespace, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE)) as $piece) { $index = $tokens->getPrevMeaningfulToken($index); if ('\\' === $piece) { if (!$tokens[$index]->isGivenKind(T_NS_SEPARATOR)) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleClassElementPerStatementFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleClassElementPerStatementFixer.php index 2eed2464..927f3175 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleClassElementPerStatementFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleClassElementPerStatementFixer.php @@ -195,7 +195,7 @@ private function expandElement(Tokens $tokens, string $type, int $startIndex, in } /** - * @return Token[] + * @return list */ private function getModifiersSequences(Tokens $tokens, string $type, int $startIndex, int $endIndex): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleTraitInsertPerStatementFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleTraitInsertPerStatementFixer.php index ec20f3ca..03eb845a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleTraitInsertPerStatementFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ClassNotation/SingleTraitInsertPerStatementFixer.php @@ -70,7 +70,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param int[] $candidates ',' indices to fix + * @param list $candidates ',' indices to fix */ private function fixTraitUse(Tokens $tokens, int $useTraitIndex, array $candidates): void { @@ -95,7 +95,7 @@ private function fixTraitUse(Tokens $tokens, int $useTraitIndex, array $candidat } /** - * @return int[] + * @return list */ private function getCandidates(Tokens $tokens, int $index): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/CommentToPhpdocFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/CommentToPhpdocFixer.php index 61026059..d443231f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/CommentToPhpdocFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/CommentToPhpdocFixer.php @@ -35,7 +35,7 @@ final class CommentToPhpdocFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { /** - * @var string[] + * @var list */ private array $ignoredTags = []; @@ -52,7 +52,7 @@ public function isRisky(): bool /** * {@inheritdoc} * - * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToCommentFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. + * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocArrayTypeFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToCommentFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. * Must run after AlignMultilineCommentFixer. */ public function getPriority(): int @@ -124,7 +124,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param int[] $indices + * @param list $indices */ private function isCommentCandidate(Tokens $tokens, array $indices): bool { @@ -134,7 +134,7 @@ function (bool $carry, int $index) use ($tokens): bool { if ($carry) { return true; } - if (!Preg::match('~(?:#|//|/\*+|\R(?:\s*\*)?)\s*\@([a-zA-Z0-9_\\\\-]+)(?=\s|\(|$)~', $tokens[$index]->getContent(), $matches)) { + if (!Preg::match('~(?:#|//|/\*+|\R(?:\s*\*)?)\s*\@([a-zA-Z0-9_\\\-]+)(?=\s|\(|$)~', $tokens[$index]->getContent(), $matches)) { return false; } @@ -145,12 +145,12 @@ function (bool $carry, int $index) use ($tokens): bool { } /** - * @param int[] $indices + * @param non-empty-list $indices */ private function fixComment(Tokens $tokens, array $indices): void { if (1 === \count($indices)) { - $this->fixCommentSingleLine($tokens, reset($indices)); + $this->fixCommentSingleLine($tokens, $indices[0]); } else { $this->fixCommentMultiLine($tokens, $indices); } @@ -172,11 +172,11 @@ private function fixCommentSingleLine(Tokens $tokens, int $index): void } /** - * @param int[] $indices + * @param non-empty-list $indices */ private function fixCommentMultiLine(Tokens $tokens, array $indices): void { - $startIndex = reset($indices); + $startIndex = $indices[0]; $indent = Utils::calculateTrailingWhitespaceIndent($tokens[$startIndex - 1]); $newContent = '/**'.$this->whitespacesConfig->getLineEnding(); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/HeaderCommentFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/HeaderCommentFixer.php index e6da49d8..1915cf23 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/HeaderCommentFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/HeaderCommentFixer.php @@ -112,7 +112,7 @@ public function getDefinition(): FixerDefinitionInterface public function isCandidate(Tokens $tokens): bool { - return $tokens->isMonolithicPhp(); + return $tokens->isMonolithicPhp() && !$tokens->isTokenKindFound(T_OPEN_TAG_WITH_ECHO); } /** @@ -266,11 +266,7 @@ private function findHeaderCommentCurrentIndex(Tokens $tokens, int $headerNewInd */ private function findHeaderCommentInsertionIndex(Tokens $tokens, string $location): int { - $openTagIndex = $tokens[0]->isGivenKind(T_OPEN_TAG) ? 0 : $tokens->getNextTokenOfKind(0, [[T_OPEN_TAG]]); - - if (null === $openTagIndex) { - return 1; - } + $openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0; if ('after_open' === $location) { return $openTagIndex + 1; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/MultilineCommentOpeningClosingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/MultilineCommentOpeningClosingFixer.php index dc4b7dc3..055c701b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/MultilineCommentOpeningClosingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/MultilineCommentOpeningClosingFixer.php @@ -75,11 +75,11 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // Fix opening if ($token->isGivenKind(T_COMMENT)) { - $newContent = Preg::replace('/^\\/\\*{2,}(?!\\/)/', '/*', $newContent); + $newContent = Preg::replace('/^\/\*{2,}(?!\/)/', '/*', $newContent); } // Fix closing - $newContent = Preg::replace('/(?getId(), $newContent]); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/NoEmptyCommentFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/NoEmptyCommentFixer.php index c2d6c744..23f0b1a3 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/NoEmptyCommentFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/NoEmptyCommentFixer.php @@ -60,7 +60,11 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - [$blockStart, $index, $isEmpty] = $this->getCommentBlock($tokens, $index); + $blockInfo = $this->getCommentBlock($tokens, $index); + $blockStart = $blockInfo['blockStart']; + $index = $blockInfo['blockEnd']; + $isEmpty = $blockInfo['isEmpty']; + if (false === $isEmpty) { continue; } @@ -75,6 +79,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void * Return the start index, end index and a flag stating if the comment block is empty. * * @param int $index T_COMMENT index + * + * @return array{blockStart: int, blockEnd: int, isEmpty: bool} */ private function getCommentBlock(Tokens $tokens, int $index): array { @@ -82,7 +88,11 @@ private function getCommentBlock(Tokens $tokens, int $index): array $empty = $this->isEmptyComment($tokens[$index]->getContent()); if (self::TYPE_SLASH_ASTERISK === $commentType) { - return [$index, $index, $empty]; + return [ + 'blockStart' => $index, + 'blockEnd' => $index, + 'isEmpty' => $empty, + ]; } $start = $index; @@ -107,7 +117,11 @@ private function getCommentBlock(Tokens $tokens, int $index): array } } - return [$start, $index - 1, $empty]; + return [ + 'blockStart' => $start, + 'blockEnd' => $index - 1, + 'isEmpty' => $empty, + ]; } private function getCommentType(string $content): int diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/SingleLineCommentStyleFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/SingleLineCommentStyleFixer.php index aaf81ed9..f0b38658 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/SingleLineCommentStyleFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Comment/SingleLineCommentStyleFixer.php @@ -119,7 +119,9 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } $content = $token->getContent(); - $commentContent = substr($content, 2, -2) ?: ''; + + /** @TODO PHP 8.0 - no more need for `?: ''` */ + $commentContent = substr($content, 2, -2) ?: ''; // @phpstan-ignore-line if ($this->hashEnabled && str_starts_with($content, '#')) { if (isset($content[1]) && '[' === $content[1]) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/EmptyLoopConditionFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/EmptyLoopConditionFixer.php index 6e3c81fc..0e48012b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/EmptyLoopConditionFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/EmptyLoopConditionFixer.php @@ -131,7 +131,7 @@ private static function clearNotCommentsInRange(Tokens $tokens, int $indexStart, } /** - * @param Token[] $replacement + * @param list $replacement */ private static function cloneAndInsert(Tokens $tokens, int $index, array $replacement): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoBreakCommentFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoBreakCommentFixer.php index b50a6c85..eca95427 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoBreakCommentFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoBreakCommentFixer.php @@ -335,7 +335,7 @@ private function getStructureEnd(Tokens $tokens, int $position): int } /** - * @return array + * @return list */ private static function getParenthesisedStructureKinds(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededBracesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededBracesFixer.php index 281eca16..3d1e72bc 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededBracesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededBracesFixer.php @@ -134,9 +134,17 @@ private function clearIfIsOverCompleteNamespaceBlock(Tokens $tokens): void $index = $tokens->getNextTokenOfKind(0, [[T_NAMESPACE]]); - do { + $namespaceIsNamed = false; + + $index = $tokens->getNextMeaningfulToken($index); + while ($tokens[$index]->isGivenKind([T_STRING, T_NS_SEPARATOR])) { $index = $tokens->getNextMeaningfulToken($index); - } while ($tokens[$index]->isGivenKind([T_STRING, T_NS_SEPARATOR])); + $namespaceIsNamed = true; + } + + if (!$namespaceIsNamed) { + return; + } if (!$tokens[$index]->equals('{')) { return; // `;` diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php index b0156c27..b924eed6 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php @@ -36,7 +36,7 @@ final class NoUnneededControlParenthesesFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var int[] + * @var list */ private const BLOCK_TYPES = [ Tokens::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE, @@ -102,7 +102,7 @@ final class NoUnneededControlParenthesesFixer extends AbstractFixer implements C ]; /** - * @var list|string> + * @var list */ private array $noopTypes; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SimplifiedIfReturnFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SimplifiedIfReturnFixer.php index 9710a9fd..a3633700 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SimplifiedIfReturnFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SimplifiedIfReturnFixer.php @@ -27,7 +27,7 @@ final class SimplifiedIfReturnFixer extends AbstractFixer { /** - * @var list|string>}> + * @var list}> */ private array $sequences = [ [ @@ -106,7 +106,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - $firstSequenceIndex = key($sequenceFound); + $firstSequenceIndex = array_key_first($sequenceFound); if ($firstSequenceIndex !== $firstCandidateIndex) { continue; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SwitchContinueToBreakFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SwitchContinueToBreakFixer.php index 23b523a8..b42fc3a9 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SwitchContinueToBreakFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/SwitchContinueToBreakFixer.php @@ -25,7 +25,7 @@ final class SwitchContinueToBreakFixer extends AbstractFixer { /** - * @var int[] + * @var list */ private array $switchLevels = []; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/TrailingCommaInMultilineFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/TrailingCommaInMultilineFixer.php index 19cfffe8..f5a5f8ff 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/TrailingCommaInMultilineFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/TrailingCommaInMultilineFixer.php @@ -98,7 +98,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setAllowedTypes(['array']) ->setAllowedValues([new AllowedValueSubset([self::ELEMENTS_ARRAYS, self::ELEMENTS_ARGUMENTS, self::ELEMENTS_PARAMETERS, self::MATCH_EXPRESSIONS])]) ->setDefault([self::ELEMENTS_ARRAYS]) - ->setNormalizer(static function (Options $options, $value) { + ->setNormalizer(static function (Options $options, array $value) { if (\PHP_VERSION_ID < 8_00_00) { // @TODO: drop condition when PHP 8.0+ is required foreach ([self::ELEMENTS_PARAMETERS, self::MATCH_EXPRESSIONS] as $option) { if (\in_array($option, $value, true)) { @@ -142,7 +142,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $prevPrevIndex = $tokens->getPrevMeaningfulToken($prevIndex); if ($fixArguments - && $tokens[$prevIndex]->equalsAny([']', [T_CLASS], [T_STRING], [T_VARIABLE], [T_STATIC]]) + && $tokens[$prevIndex]->equalsAny([']', [T_CLASS], [T_STRING], [T_VARIABLE], [T_STATIC], [T_ISSET], [T_UNSET], [T_LIST]]) && !$tokens[$prevPrevIndex]->isGivenKind(T_FUNCTION) ) { $this->fixBlock($tokens, $index); @@ -153,7 +153,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void if ( $fixParameters && ( - $tokens[$prevIndex]->isGivenKind(T_STRING) && $tokens[$prevPrevIndex]->isGivenKind(T_FUNCTION) + $tokens[$prevIndex]->isGivenKind(T_STRING) + && $tokens[$prevPrevIndex]->isGivenKind(T_FUNCTION) || $tokens[$prevIndex]->isGivenKind([T_FN, T_FUNCTION]) ) ) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/YodaStyleFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/YodaStyleFixer.php index 0a267465..c8005f1b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/YodaStyleFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ControlStructure/YodaStyleFixer.php @@ -44,7 +44,7 @@ final class YodaStyleFixer extends AbstractFixer implements ConfigurableFixerInt private $candidateTypesConfiguration; /** - * @var array + * @var list */ private $candidateTypes; @@ -345,6 +345,9 @@ private function fixTokensComparePart(Tokens $tokens, int $start, int $end): Tok return $newTokens; } + /** + * @return null|array{left: array{start: int, end: int}, right: array{start: int, end: int}} + */ private function getCompareFixableInfo(Tokens $tokens, int $index, bool $yoda): ?array { $right = $this->getRightSideCompareFixableInfo($tokens, $index); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/DeprecatedFixerInterface.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/DeprecatedFixerInterface.php index 6d7d7e84..eded1614 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/DeprecatedFixerInterface.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/DeprecatedFixerInterface.php @@ -22,7 +22,7 @@ interface DeprecatedFixerInterface extends FixerInterface /** * Returns names of fixers to use instead, if any. * - * @return string[] + * @return list */ public function getSuccessorsNames(): array; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationIndentationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationIndentationFixer.php index 1359aef0..58ae532b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationIndentationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/DoctrineAnnotation/DoctrineAnnotationIndentationFixer.php @@ -105,7 +105,7 @@ protected function fixAnnotations(Tokens $doctrineAnnotationTokens): void } /** - * @return int[] + * @return array{int, int} */ private function getLineBracesCount(Tokens $tokens, int $index): array { @@ -157,7 +157,7 @@ private function isClosingLineWithMeaningfulContent(Tokens $tokens, int $index): } /** - * @param array> $annotationPositions Pairs of begin and end indices of main annotations + * @param list $annotationPositions Pairs of begin and end indices of main annotations */ private function indentationCanBeFixed(Tokens $tokens, int $newLineTokenIndex, array $annotationPositions): bool { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ExperimentalFixerInterface.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ExperimentalFixerInterface.php new file mode 100644 index 00000000..9ade1875 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ExperimentalFixerInterface.php @@ -0,0 +1,20 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer; + +/** + * @internal + */ +interface ExperimentalFixerInterface extends FixerInterface {} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/CombineNestedDirnameFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/CombineNestedDirnameFixer.php index 7a180998..a96f73fe 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/CombineNestedDirnameFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/CombineNestedDirnameFixer.php @@ -67,7 +67,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void for ($index = $tokens->count() - 1; 0 <= $index; --$index) { $dirnameInfo = $this->getDirnameInfo($tokens, $index); - if (!$dirnameInfo) { + if (false === $dirnameInfo) { continue; } @@ -105,7 +105,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void * @param int $index Index of `dirname` * @param null|int $firstArgumentEndIndex Index of last token of first argument of `dirname` call * - * @return array{indices: list, secondArgument?: int, levels: int, end: int}|bool `false` when it is not a (supported) `dirname` call, an array with info about the dirname call otherwise + * @return array{indices: list, secondArgument?: int, levels: int, end: int}|false `false` when it is not a (supported) `dirname` call, an array with info about the dirname call otherwise */ private function getDirnameInfo(Tokens $tokens, int $index, ?int $firstArgumentEndIndex = null) { @@ -189,7 +189,7 @@ private function getDirnameInfo(Tokens $tokens, int $index, ?int $firstArgumentE } /** - * @param array, secondArgument?: int, levels: int, end: int}> $dirnameInfoArray + * @param non-empty-list, secondArgument?: int, levels: int, end: int}> $dirnameInfoArray */ private function combineDirnames(Tokens $tokens, array $dirnameInfoArray): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php index 5c72fcf2..55ff455c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/DateTimeCreateFromFormatCallFixer.php @@ -87,7 +87,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $classNameIndex = $tokens->getPrevMeaningfulToken($index); - if (!$tokens[$classNameIndex]->equalsAny([[T_STRING, 'DateTime'], [T_STRING, 'DateTimeImmutable']], false)) { + if (!$tokens[$classNameIndex]->equalsAny([[T_STRING, \DateTime::class], [T_STRING, \DateTimeImmutable::class]], false)) { continue; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/FopenFlagOrderFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/FopenFlagOrderFixer.php index edf0bf6c..3bf72e22 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/FopenFlagOrderFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/FopenFlagOrderFixer.php @@ -85,9 +85,9 @@ protected function fixFopenFlagToken(Tokens $tokens, int $argumentStartIndex, in } /** - * @param string[] $flags + * @param list $flags * - * @return string[] + * @return list */ private function sortFlags(array $flags): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/ImplodeCallFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/ImplodeCallFixer.php index 49d728ef..4561c393 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/ImplodeCallFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/ImplodeCallFixer.php @@ -78,7 +78,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $argumentsIndices = $this->getArgumentIndices($tokens, $index); if (1 === \count($argumentsIndices)) { - $firstArgumentIndex = key($argumentsIndices); + $firstArgumentIndex = array_key_first($argumentsIndices); $tokens->insertAt($firstArgumentIndex, [ new Token([T_CONSTANT_ENCAPSED_STRING, "''"]), new Token(','), @@ -103,7 +103,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // collect tokens from first argument $firstArgumentEndIndex = $argumentsIndices[key($argumentsIndices)]; $newSecondArgumentTokens = []; - for ($i = key($argumentsIndices); $i <= $firstArgumentEndIndex; ++$i) { + for ($i = array_key_first($argumentsIndices); $i <= $firstArgumentEndIndex; ++$i) { $newSecondArgumentTokens[] = clone $tokens[$i]; $tokens->clearAt($i); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/LambdaNotUsedImportFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/LambdaNotUsedImportFixer.php index 48155cec..e026637c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/LambdaNotUsedImportFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/LambdaNotUsedImportFixer.php @@ -108,6 +108,8 @@ private function fixLambda(Tokens $tokens, int $lambdaUseIndex): void } /** + * @param array $imports + * * @return array */ private function findNotUsedLambdaImports(Tokens $tokens, array $imports, int $lambdaUseCloseBraceIndex): array @@ -234,6 +236,12 @@ private function findNotUsedLambdaImports(Tokens $tokens, array $imports, int $l return $imports; } + /** + * @param array $imports + * @param array $arguments + * + * @return array + */ private function countImportsUsedAsArgument(Tokens $tokens, array $imports, array $arguments): array { foreach ($arguments as $start => $end) { @@ -277,6 +285,11 @@ private function getLambdaUseIndex(Tokens $tokens, int $index) return $lambdaUseIndex; } + /** + * @param array $arguments + * + * @return array + */ private function filterArguments(Tokens $tokens, array $arguments): array { $imports = []; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php index 5f47784e..2b6e3f2c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/MethodArgumentSpaceFixer.php @@ -301,7 +301,7 @@ private function ensureFunctionFullyMultiline(Tokens $tokens, int $startFunction do { $prevWhitespaceTokenIndex = $tokens->getPrevTokenOfKind( $searchIndex, - [[T_WHITESPACE]] + [[T_ENCAPSED_AND_WHITESPACE], [T_WHITESPACE]], ); $searchIndex = $prevWhitespaceTokenIndex; @@ -311,6 +311,8 @@ private function ensureFunctionFullyMultiline(Tokens $tokens, int $startFunction if (null === $prevWhitespaceTokenIndex) { $existingIndentation = ''; + } elseif (!$tokens[$prevWhitespaceTokenIndex]->isGivenKind(T_WHITESPACE)) { + return; } else { $existingIndentation = $tokens[$prevWhitespaceTokenIndex]->getContent(); $lastLineIndex = strrpos($existingIndentation, "\n"); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NativeFunctionInvocationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NativeFunctionInvocationFixer.php index 06f9b660..f726e467 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NativeFunctionInvocationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NativeFunctionInvocationFixer.php @@ -385,17 +385,18 @@ private function getAllInternalFunctionsNormalized(): array } /** - * @param string[] $functionNames + * @param list $functionNames * * @return array all function names lower cased */ private function normalizeFunctionNames(array $functionNames): array { - foreach ($functionNames as $index => $functionName) { - $functionNames[strtolower($functionName)] = true; - unset($functionNames[$index]); + $result = []; + + foreach ($functionNames as $functionName) { + $result[strtolower($functionName)] = true; } - return $functionNames; + return $result; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NoSpacesAfterFunctionNameFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NoSpacesAfterFunctionNameFixer.php index 9549b45a..a63e9914 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NoSpacesAfterFunctionNameFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NoSpacesAfterFunctionNameFixer.php @@ -33,7 +33,7 @@ public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( 'When making a method or function call, there MUST NOT be a space between the method or function name and the opening parenthesis.', - [new CodeSample("isAnyTokenKindsFound(array_merge($this->getFunctionyTokenKinds(), [T_STRING])); + return $tokens->isAnyTokenKindsFound([T_STRING, ...$this->getFunctionyTokenKinds()]); } protected function applyFix(\SplFileInfo $file, Tokens $tokens): void @@ -73,7 +73,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $nextNonWhiteSpace = $tokens->getNextMeaningfulToken($endParenthesisIndex); if ( null !== $nextNonWhiteSpace - && $tokens[$nextNonWhiteSpace]->equals('?') + && !$tokens[$nextNonWhiteSpace]->equals(';') && $tokens[$lastTokenIndex]->isGivenKind($languageConstructionTokens) ) { continue; @@ -116,24 +116,22 @@ private function fixFunctionCall(Tokens $tokens, int $index): void } /** - * @return array|string> + * @return list */ private function getBraceAfterVariableKinds(): array { - static $tokens = [ + return [ ')', ']', [CT::T_DYNAMIC_VAR_BRACE_CLOSE], [CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE], ]; - - return $tokens; } /** * Gets the token kinds which can work as function calls. * - * @return int[] Token names + * @return list Token names */ private function getFunctionyTokenKinds(): array { @@ -160,7 +158,7 @@ private function getFunctionyTokenKinds(): array /** * Gets the token kinds of actually language construction. * - * @return int[] + * @return list */ private function getLanguageConstructionTokenKinds(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NullableTypeDeclarationForDefaultNullValueFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NullableTypeDeclarationForDefaultNullValueFixer.php index a8cec92c..efebad87 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NullableTypeDeclarationForDefaultNullValueFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/NullableTypeDeclarationForDefaultNullValueFixer.php @@ -92,6 +92,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn (new FixerOptionBuilder('use_nullable_type_declaration', 'Whether to add or remove `?` or `|null` to parameters with a default `null` value.')) ->setAllowedTypes(['bool']) ->setDefault(true) + ->setDeprecationMessage('Behaviour will follow default one.') // @TODO remove the option on next major 4.0 ->getOption(), ]); } @@ -114,7 +115,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param ArgumentAnalysis[] $arguments + * @param array $arguments */ private function fixFunctionParameters(Tokens $tokens, array $arguments): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php index 2ab13430..603051f2 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php @@ -16,6 +16,7 @@ use PhpCsFixer\AbstractPhpdocToTypeDeclarationFixer; use PhpCsFixer\DocBlock\Annotation; +use PhpCsFixer\Fixer\ExperimentalFixerInterface; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; @@ -25,12 +26,12 @@ /** * @author Jan Gantzert */ -final class PhpdocToParamTypeFixer extends AbstractPhpdocToTypeDeclarationFixer +final class PhpdocToParamTypeFixer extends AbstractPhpdocToTypeDeclarationFixer implements ExperimentalFixerInterface { private const TYPE_CHECK_TEMPLATE = ' */ private const EXCLUDE_FUNC_NAMES = [ [T_STRING, '__clone'], @@ -49,7 +50,7 @@ final class PhpdocToParamTypeFixer extends AbstractPhpdocToTypeDeclarationFixer public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( - 'EXPERIMENTAL: Takes `@param` annotations of non-mixed types and adjusts accordingly the function signature. Requires PHP >= 7.0.', + 'Takes `@param` annotations of non-mixed types and adjusts accordingly the function signature. Requires PHP >= 7.0.', [ new CodeSample( ' false] ), + new CodeSample( + ' false] + ), ], null, - 'This rule is EXPERIMENTAL and [1] is not covered with backward compatibility promise. [2] `@param` annotation is mandatory for the fixer to make changes, signatures of methods without it (no docblock, inheritdocs) will not be fixed. [3] Manual actions are required if inherited signatures are not properly documented.' + 'The `@param` annotation is mandatory for the fixer to make changes, signatures of methods without it (no docblock, inheritdocs) will not be fixed. Manual actions are required if inherited signatures are not properly documented.' ); } public function isCandidate(Tokens $tokens): bool { - return $tokens->isTokenKindFound(T_FUNCTION); + return $tokens->isAnyTokenKindsFound([T_FUNCTION, T_FN]); } /** @@ -102,7 +113,7 @@ protected function isSkippedType(string $type): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { for ($index = $tokens->count() - 1; 0 < $index; --$index) { - if (!$tokens[$index]->isGivenKind(T_FUNCTION)) { + if (!$tokens[$index]->isGivenKind([T_FUNCTION, T_FN])) { continue; } @@ -136,7 +147,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } if (null !== $typeInfo) { - [$paramType, $isNullable] = $typeInfo; + $paramType = $typeInfo['commonType']; + $isNullable = $typeInfo['isNullable']; } elseif (null !== $unionTypes) { $paramType = $unionTypes; $isNullable = false; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToPropertyTypeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToPropertyTypeFixer.php index 7a1f287e..7467c008 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToPropertyTypeFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToPropertyTypeFixer.php @@ -16,13 +16,17 @@ use PhpCsFixer\AbstractPhpdocToTypeDeclarationFixer; use PhpCsFixer\DocBlock\Annotation; +use PhpCsFixer\Fixer\ExperimentalFixerInterface; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; -final class PhpdocToPropertyTypeFixer extends AbstractPhpdocToTypeDeclarationFixer +/** + * @phpstan-import-type _CommonTypeInfo from AbstractPhpdocToTypeDeclarationFixer + */ +final class PhpdocToPropertyTypeFixer extends AbstractPhpdocToTypeDeclarationFixer implements ExperimentalFixerInterface { private const TYPE_CHECK_TEMPLATE = '= 7.4.', + 'Takes `@var` annotation of non-mixed types and adjusts accordingly the property signature. Requires PHP >= 7.4.', [ new CodeSample( ' false] ), + new CodeSample( + ' false] + ), ], null, - 'This rule is EXPERIMENTAL and [1] is not covered with backward compatibility promise. [2] `@var` annotation is mandatory for the fixer to make changes, signatures of properties without it (no docblock) will not be fixed. [3] Manual actions might be required for newly typed properties that are read before initialization.' + 'The `@var` annotation is mandatory for the fixer to make changes, signatures of properties without it (no docblock) will not be fixed. Manual actions might be required for newly typed properties that are read before initialization.' ); } @@ -142,7 +157,8 @@ private function fixClass(Tokens $tokens, int $index): void continue; } - [$propertyType, $isNullable] = $typeInfo; + $propertyType = $typeInfo['commonType']; + $isNullable = $typeInfo['isNullable']; if (\in_array($propertyType, ['callable', 'never', 'void'], true)) { continue; @@ -198,7 +214,9 @@ private function findNextUntypedPropertiesDeclaration(Tokens $tokens, int $index /** * @param array $propertyIndices - * @param Annotation[] $annotations + * @param list $annotations + * + * @return ?_CommonTypeInfo */ private function resolveApplicableType(array $propertyIndices, array $annotations): ?array { @@ -212,7 +230,7 @@ private function resolveApplicableType(array $propertyIndices, array $annotation continue; } - $propertyName = key($propertyIndices); + $propertyName = array_key_first($propertyIndices); } if (!isset($propertyIndices[$propertyName])) { @@ -237,7 +255,7 @@ private function resolveApplicableType(array $propertyIndices, array $annotation } if (null !== $unionTypes) { - $typeInfo = [$unionTypes, false]; + $typeInfo = ['commonType' => $unionTypes, 'isNullable' => false]; } if (\array_key_exists($propertyName, $propertyTypes) && $typeInfo !== $propertyTypes[$propertyName]) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToReturnTypeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToReturnTypeFixer.php index 5ce5f9db..7b029da2 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToReturnTypeFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/PhpdocToReturnTypeFixer.php @@ -15,7 +15,7 @@ namespace PhpCsFixer\Fixer\FunctionNotation; use PhpCsFixer\AbstractPhpdocToTypeDeclarationFixer; -use PhpCsFixer\DocBlock\Annotation; +use PhpCsFixer\Fixer\ExperimentalFixerInterface; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; @@ -28,7 +28,7 @@ /** * @author Filippo Tessarotto */ -final class PhpdocToReturnTypeFixer extends AbstractPhpdocToTypeDeclarationFixer +final class PhpdocToReturnTypeFixer extends AbstractPhpdocToTypeDeclarationFixer implements ExperimentalFixerInterface { private const TYPE_CHECK_TEMPLATE = ' false] ), + new CodeSample( + ' false] + ), new VersionSpecificCodeSample( 'getTypeExpression(); @@ -164,7 +173,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } if (null !== $typeInfo) { - [$returnType, $isNullable] = $typeInfo; + $returnType = $typeInfo['commonType']; + $isNullable = $typeInfo['isNullable']; } elseif (null !== $unionTypes) { $returnType = $unionTypes; $isNullable = false; @@ -174,9 +184,12 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - $startIndex = $tokens->getNextTokenOfKind($index, ['{', ';']); + $paramsStartIndex = $tokens->getNextTokenOfKind($index, ['(']); + $paramsEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $paramsStartIndex); - if ($this->hasReturnTypeHint($tokens, $startIndex)) { + $bodyStartIndex = $tokens->getNextTokenOfKind($paramsEndIndex, ['{', ';', [T_DOUBLE_ARROW]]); + + if ($this->hasReturnTypeHint($tokens, $bodyStartIndex)) { continue; } @@ -184,10 +197,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - $endFuncIndex = $tokens->getPrevTokenOfKind($startIndex, [')']); - $tokens->insertAt( - $endFuncIndex + 1, + $paramsEndIndex + 1, array_merge( [ new Token([CT::T_TYPE_COLON, ':']), diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/RegularCallableCallFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/RegularCallableCallFixer.php index 2bb372c3..7538ff7a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/RegularCallableCallFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/RegularCallableCallFixer.php @@ -103,7 +103,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param array $arguments + * @param non-empty-array $arguments */ private function processCall(Tokens $tokens, int $index, array $arguments): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/VoidReturnFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/VoidReturnFixer.php index 65e8268d..150931dd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/VoidReturnFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/FunctionNotation/VoidReturnFixer.php @@ -220,7 +220,7 @@ private function fixFunctionDefinition(Tokens $tokens, int $index): void * * @param int $index The index of the function token * - * @return Annotation[] + * @return list */ private function findReturnAnnotations(Tokens $tokens, int $index): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/FullyQualifiedStrictTypesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/FullyQualifiedStrictTypesFixer.php index e9f04f3c..5522dafd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/FullyQualifiedStrictTypesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/FullyQualifiedStrictTypesFixer.php @@ -15,44 +15,111 @@ namespace PhpCsFixer\Fixer\Import; use PhpCsFixer\AbstractFixer; +use PhpCsFixer\DocBlock\TypeExpression; use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface; use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; use PhpCsFixer\Tokenizer\Analyzer\Analysis\TypeAnalysis; +use PhpCsFixer\Tokenizer\Analyzer\AttributeAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer; use PhpCsFixer\Tokenizer\CT; +use PhpCsFixer\Tokenizer\Processor\ImportProcessor; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; /** * @author VeeWee + * @author Tomas Jadrny + * @author Greg Korba + * @author SpacePossum + * @author Michael Vorisek */ -final class FullyQualifiedStrictTypesFixer extends AbstractFixer implements ConfigurableFixerInterface +final class FullyQualifiedStrictTypesFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { + private const REGEX_CLASS = '(?:\\\?+'.TypeExpression::REGEX_IDENTIFIER + .'(\\\\'.TypeExpression::REGEX_IDENTIFIER.')*+)'; + + /** + * @var array{ + * const?: list, + * class?: list, + * function?: list + * }|null + */ + private ?array $discoveredSymbols; + + /** + * @var array{ + * const?: array, + * class?: array, + * function?: array + * } + */ + private array $symbolsForImport = []; + + /** + * @var array, array> + */ + private array $reservedIdentifiersByLevel; + + /** @var array */ + private array $cacheUsesLast = []; + + /** @var array */ + private array $cacheUseNameByShortNameLower; + + /** @var array */ + private array $cacheUseShortNameByNameLower; + public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( - 'Transforms imported FQCN parameters and return types in function arguments to short version.', + 'Removes the leading part of fully qualified symbol references if a given symbol is imported or belongs to the current namespace.', [ new CodeSample( 'baz = $baz; } - public function doY(Foo\NotImported $u, \Foo\NotImported $v) + /** + * @return \Foo\Bar\Baz + */ + public function getBaz() { + return $this->baz; + } + + public function doX(\Foo\Bar $foo, \Exception $e): \Foo\Bar\Baz { + try {} + catch (\Foo\SomeException $e) {} } } ' @@ -69,6 +136,43 @@ public function doY(Foo\NotImported $u, \Foo\NotImported $v) ', ['leading_backslash_in_global_namespace' => true] ), + new CodeSample( + ' true] + ), + new CodeSample( + ' true] + ), ] ); } @@ -76,8 +180,8 @@ public function doY(Foo\NotImported $u, \Foo\NotImported $v) /** * {@inheritdoc} * - * Must run before NoSuperfluousPhpdocTagsFixer. - * Must run after PhpdocToReturnTypeFixer. + * Must run before NoSuperfluousPhpdocTagsFixer, OrderedAttributesFixer, OrderedImportsFixer, OrderedInterfacesFixer, StatementIndentationFixer. + * Must run after ClassKeywordFixer, PhpUnitAttributesFixer, PhpdocToReturnTypeFixer. */ public function getPriority(): int { @@ -86,7 +190,19 @@ public function getPriority(): int public function isCandidate(Tokens $tokens): bool { - return $tokens->isTokenKindFound(T_FUNCTION); + return $tokens->isAnyTokenKindsFound([ + CT::T_USE_TRAIT, + ...(\defined('T_ATTRIBUTE') ? [T_ATTRIBUTE] : []), // @TODO: drop condition when PHP 8.0+ is required + T_CATCH, + T_DOUBLE_COLON, + T_DOC_COMMENT, + T_EXTENDS, + T_FUNCTION, + T_IMPLEMENTS, + T_INSTANCEOF, + T_NEW, + T_VARIABLE, + ]); } protected function createConfigurationDefinition(): FixerConfigurationResolverInterface @@ -99,6 +215,41 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setAllowedTypes(['bool']) ->setDefault(false) ->getOption(), + (new FixerOptionBuilder( + 'import_symbols', + 'Whether FQCNs should be automatically imported.' + )) + ->setAllowedTypes(['bool']) + ->setDefault(false) + ->getOption(), + (new FixerOptionBuilder( + 'phpdoc_tags', + 'Collection of PHPDoc annotation tags where FQCNs should be processed. As of now only simple tags with `@tag \F\Q\C\N` format are supported (no complex types).' + )) + ->setAllowedTypes(['array']) + ->setDefault([ + 'param', + 'phpstan-param', + 'phpstan-property', + 'phpstan-property-read', + 'phpstan-property-write', + 'phpstan-return', + 'phpstan-var', + 'property', + 'property-read', + 'property-write', + 'psalm-param', + 'psalm-property', + 'psalm-property-read', + 'psalm-property-write', + 'psalm-return', + 'psalm-var', + 'return', + 'see', + 'throws', + 'var', + ]) + ->getOption(), ]); } @@ -107,18 +258,300 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $namespaceUsesAnalyzer = new NamespaceUsesAnalyzer(); $functionsAnalyzer = new FunctionsAnalyzer(); - foreach ($tokens->getNamespaceDeclarations() as $namespace) { - $namespaceName = strtolower($namespace->getFullName()); + $this->symbolsForImport = []; + + foreach ($tokens->getNamespaceDeclarations() as $namespaceIndex => $namespace) { + $namespace = $tokens->getNamespaceDeclarations()[$namespaceIndex]; + + $namespaceName = $namespace->getFullName(); $uses = []; + $lastUse = null; + + foreach ($namespaceUsesAnalyzer->getDeclarationsInNamespace($tokens, $namespace, true) as $use) { + if (!$use->isClass()) { + continue; + } + $uses[ltrim($use->getFullName(), '\\')] = $use->getShortName(); + $lastUse = $use; + } + + $indexDiff = 0; + foreach (true === $this->configuration['import_symbols'] ? [true, false] : [false] as $discoverSymbolsPhase) { + $this->discoveredSymbols = $discoverSymbolsPhase ? [] : null; + + $classyKinds = [T_CLASS, T_INTERFACE, T_TRAIT]; + if (\defined('T_ENUM')) { // @TODO: drop condition when PHP 8.1+ is required + $classyKinds[] = T_ENUM; + } + + $openedCurlyBrackets = 0; + $this->reservedIdentifiersByLevel = []; + + for ($index = $namespace->getScopeStartIndex(); $index < $namespace->getScopeEndIndex() + $indexDiff; ++$index) { + $origSize = \count($tokens); + + if ($tokens[$index]->equals('{')) { + ++$openedCurlyBrackets; + } if ($tokens[$index]->equals('}')) { + unset($this->reservedIdentifiersByLevel[$openedCurlyBrackets]); + --$openedCurlyBrackets; + } elseif ($discoverSymbolsPhase && $tokens[$index]->isGivenKind($classyKinds)) { + $this->fixNextName($tokens, $index, $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind(T_FUNCTION)) { + $this->fixFunction($functionsAnalyzer, $tokens, $index, $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind([T_EXTENDS, T_IMPLEMENTS])) { + $this->fixExtendsImplements($tokens, $index, $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind(T_CATCH)) { + $this->fixCatch($tokens, $index, $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind(T_DOUBLE_COLON)) { + $this->fixPrevName($tokens, $index, $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind([T_INSTANCEOF, T_NEW, CT::T_USE_TRAIT])) { + $this->fixNextName($tokens, $index, $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind(T_VARIABLE)) { + $prevIndex = $tokens->getPrevMeaningfulToken($index); + if (null !== $prevIndex && $tokens[$prevIndex]->isGivenKind(T_STRING)) { + $this->fixPrevName($tokens, $index, $uses, $namespaceName); + } + } elseif (\defined('T_ATTRIBUTE') && $tokens[$index]->isGivenKind(T_ATTRIBUTE)) { // @TODO: drop const check when PHP 8.0+ is required + $this->fixAttribute($tokens, $index, $uses, $namespaceName); + } elseif ($discoverSymbolsPhase && !\defined('T_ATTRIBUTE') && $tokens[$index]->isComment() && Preg::match('/#\[\s*('.self::REGEX_CLASS.')/', $tokens[$index]->getContent(), $matches)) { // @TODO: drop when PHP 8.0+ is required + $this->determineShortType($matches[1], $uses, $namespaceName); + } elseif ($tokens[$index]->isGivenKind(T_DOC_COMMENT)) { + Preg::matchAll('/\*\h*@(?:psalm-|phpstan-)?(?:template(?:-covariant|-contravariant)?|(?:import-)?type)\h+('.TypeExpression::REGEX_IDENTIFIER.')(?!\S)/i', $tokens[$index]->getContent(), $matches); + foreach ($matches[1] as $reservedIdentifier) { + $this->reservedIdentifiersByLevel[$openedCurlyBrackets + 1][$reservedIdentifier] = true; + } + + $this->fixPhpDoc($tokens, $index, $uses, $namespaceName); + } - foreach ($namespaceUsesAnalyzer->getDeclarationsInNamespace($tokens, $namespace) as $use) { - $uses[strtolower(ltrim($use->getFullName(), '\\'))] = $use->getShortName(); + $indexDiff += \count($tokens) - $origSize; + } + + $this->reservedIdentifiersByLevel = []; + + if ($discoverSymbolsPhase) { + $this->setupUsesFromDiscoveredSymbols($uses, $namespaceName); + } } - for ($index = $namespace->getScopeStartIndex(); $index < $namespace->getScopeEndIndex(); ++$index) { - if ($tokens[$index]->isGivenKind(T_FUNCTION)) { - $this->fixFunction($functionsAnalyzer, $tokens, $index, $uses, $namespaceName); + if ([] !== $this->symbolsForImport) { + if (null !== $lastUse) { + $atIndex = $lastUse->getEndIndex() + 1; + } elseif (0 !== $namespace->getEndIndex()) { + $atIndex = $namespace->getEndIndex() + 1; + } else { + $firstTokenIndex = $tokens->getNextMeaningfulToken($namespace->getScopeStartIndex()); + if (null !== $firstTokenIndex && $tokens[$firstTokenIndex]->isGivenKind(T_DECLARE)) { + $atIndex = $tokens->getNextTokenOfKind($firstTokenIndex, [';']) + 1; + } else { + $atIndex = $namespace->getScopeStartIndex() + 1; + } } + + // Insert all registered FQCNs + $this->createImportProcessor()->insertImports($tokens, $this->symbolsForImport, $atIndex); + + $this->symbolsForImport = []; + } + } + } + + /** + * @param array $uses + */ + private function refreshUsesCache(array $uses): void + { + if ($this->cacheUsesLast === $uses) { + return; + } + + $this->cacheUsesLast = $uses; + $this->cacheUseNameByShortNameLower = []; + $this->cacheUseShortNameByNameLower = []; + foreach ($uses as $useLongName => $useShortName) { + $this->cacheUseNameByShortNameLower[strtolower($useShortName)] = $useLongName; + $this->cacheUseShortNameByNameLower[strtolower($useLongName)] = $useShortName; + } + } + + private function isReservedIdentifier(string $symbol): bool + { + if (str_contains($symbol, '\\')) { // optimization only + return false; + } + + if ((new TypeAnalysis($symbol))->isReservedType()) { + return true; + } + + foreach ($this->reservedIdentifiersByLevel as $reservedIdentifiers) { + if (isset($reservedIdentifiers[$symbol])) { + return true; + } + } + + return false; + } + + /** + * Resolve absolute or relative symbol to normalized FQCN. + * + * @param array $uses + */ + private function resolveSymbol(string $symbol, array $uses, string $namespaceName): string + { + if (str_starts_with($symbol, '\\')) { + return substr($symbol, 1); + } + + if ($this->isReservedIdentifier($symbol)) { + return $symbol; + } + + $this->refreshUsesCache($uses); + + $symbolArr = explode('\\', $symbol, 2); + $shortStartNameLower = strtolower($symbolArr[0]); + if (isset($this->cacheUseNameByShortNameLower[$shortStartNameLower])) { + return $this->cacheUseNameByShortNameLower[$shortStartNameLower].(isset($symbolArr[1]) ? '\\'.$symbolArr[1] : ''); + } + + return ('' !== $namespaceName ? $namespaceName.'\\' : '').$symbol; + } + + /** + * Shorten normalized FQCN as much as possible. + * + * @param array $uses + */ + private function shortenSymbol(string $fqcn, array $uses, string $namespaceName): string + { + if ($this->isReservedIdentifier($fqcn)) { + return $fqcn; + } + + $this->refreshUsesCache($uses); + + $res = null; + + // try to shorten the name using namespace + $iMin = 0; + if (str_starts_with($fqcn, $namespaceName.'\\')) { + $tmpRes = substr($fqcn, \strlen($namespaceName) + 1); + if (!isset($this->cacheUseNameByShortNameLower[strtolower(explode('\\', $tmpRes, 2)[0])]) && !$this->isReservedIdentifier($tmpRes)) { + $res = $tmpRes; + $iMin = substr_count($namespaceName, '\\') + 1; + } + } + + // try to shorten the name using uses + $tmp = $fqcn; + for ($i = substr_count($fqcn, '\\'); $i >= $iMin; --$i) { + if (isset($this->cacheUseShortNameByNameLower[strtolower($tmp)])) { + $tmpRes = $this->cacheUseShortNameByNameLower[strtolower($tmp)].substr($fqcn, \strlen($tmp)); + if (!$this->isReservedIdentifier($tmpRes)) { + $res = $tmpRes; + + break; + } + } + + if ($i > 0) { + $tmp = substr($tmp, 0, strrpos($tmp, '\\')); + } + } + + // shortening is not possible, add leading backslash if needed + if (null === $res) { + $res = $fqcn; + if ('' !== $namespaceName + || true === $this->configuration['leading_backslash_in_global_namespace'] + || isset($this->cacheUseNameByShortNameLower[strtolower(explode('\\', $res, 2)[0])]) + ) { + $res = '\\'.$res; + } + } + + return $res; + } + + /** + * @param array $uses + */ + private function setupUsesFromDiscoveredSymbols(array &$uses, string $namespaceName): void + { + foreach ($this->discoveredSymbols as $kind => $discoveredSymbols) { + $discoveredFqcnByShortNameLower = []; + + if ('' === $namespaceName) { + foreach ($discoveredSymbols as $symbol) { + if (!str_starts_with($symbol, '\\')) { + $shortStartName = explode('\\', ltrim($symbol, '\\'), 2)[0]; + $shortStartNameLower = strtolower($shortStartName); + $discoveredFqcnByShortNameLower[$shortStartNameLower] = $this->resolveSymbol($shortStartName, $uses, $namespaceName); + } + } + } + + foreach ($uses as $useLongName => $useShortName) { + $discoveredFqcnByShortNameLower[strtolower($useShortName)] = $useLongName; + } + + $useByShortNameLower = []; + foreach ($uses as $useShortName) { + $useByShortNameLower[strtolower($useShortName)] = true; + } + + uasort($discoveredSymbols, static function ($a, $b) { + $res = str_starts_with($a, '\\') <=> str_starts_with($b, '\\'); + if (0 !== $res) { + return $res; + } + + return substr_count($a, '\\') <=> substr_count($b, '\\'); + }); + foreach ($discoveredSymbols as $symbol) { + while (true) { + $shortEndNameLower = strtolower(str_contains($symbol, '\\') ? substr($symbol, strrpos($symbol, '\\') + 1) : $symbol); + if (!isset($discoveredFqcnByShortNameLower[$shortEndNameLower])) { + $shortStartNameLower = strtolower(explode('\\', ltrim($symbol, '\\'), 2)[0]); + if (str_starts_with($symbol, '\\') || ('' === $namespaceName && !isset($useByShortNameLower[$shortStartNameLower])) + || !str_contains($symbol, '\\') + ) { + $discoveredFqcnByShortNameLower[$shortEndNameLower] = $this->resolveSymbol($symbol, $uses, $namespaceName); + + break; + } + } + // else short name collision - keep unimported + + if (str_starts_with($symbol, '\\') || '' === $namespaceName || !str_contains($symbol, '\\')) { + break; + } + + $symbol = substr($symbol, 0, strrpos($symbol, '\\')); + } + } + + foreach ($uses as $useLongName => $useShortName) { + $discoveredLongName = $discoveredFqcnByShortNameLower[strtolower($useShortName)] ?? null; + if (strtolower($discoveredLongName) === strtolower($useLongName)) { + unset($discoveredFqcnByShortNameLower[strtolower($useShortName)]); + } + } + + foreach ($discoveredFqcnByShortNameLower as $fqcn) { + $shortenedName = ltrim($this->shortenSymbol($fqcn, [], $namespaceName), '\\'); + if (str_contains($shortenedName, '\\')) { // prevent importing non-namespaced names in global namespace + $shortEndName = str_contains($fqcn, '\\') ? substr($fqcn, strrpos($fqcn, '\\') + 1) : $fqcn; + $uses[$fqcn] = $shortEndName; + $this->symbolsForImport[$kind][$shortEndName] = $fqcn; + } + } + + if (isset($this->symbolsForImport[$kind])) { + ksort($this->symbolsForImport[$kind], SORT_NATURAL); } } } @@ -148,91 +581,261 @@ private function fixFunction(FunctionsAnalyzer $functionsAnalyzer, Tokens $token /** * @param array $uses */ - private function replaceByShortType(Tokens $tokens, TypeAnalysis $type, array $uses, string $namespaceName): void + private function fixPhpDoc(Tokens $tokens, int $index, array $uses, string $namespaceName): void { - $typeStartIndex = $type->getStartIndex(); + $allowedTags = $this->configuration['phpdoc_tags']; - if ($tokens[$typeStartIndex]->isGivenKind(CT::T_NULLABLE_TYPE)) { - $typeStartIndex = $tokens->getNextMeaningfulToken($typeStartIndex); + if ([] === $allowedTags) { + return; } - $namespaceNameLength = \strlen($namespaceName); - $types = $this->getTypes($tokens, $typeStartIndex, $type->getEndIndex()); + $phpDoc = $tokens[$index]; + $phpDocContent = $phpDoc->getContent(); + $phpDocContentNew = Preg::replaceCallback('/([*{]\h*@)(\S+)(\h+)('.TypeExpression::REGEX_TYPES.')(?!(?!\})\S)/', function ($matches) use ($allowedTags, $uses, $namespaceName) { + if (!\in_array($matches[2], $allowedTags, true)) { + return $matches[0]; + } + + /** @TODO parse the complex type using TypeExpression and fix all names inside (like `list<\Foo\Bar|'a|b|c'|string>` or `\Foo\Bar[]`) */ + $unsupported = false; + + return $matches[1].$matches[2].$matches[3].implode('|', array_map(function ($v) use ($uses, $namespaceName, &$unsupported) { + if ($unsupported || !Preg::match('/^'.self::REGEX_CLASS.'$/', $v)) { + $unsupported = true; + + return $v; + } + + $shortTokens = $this->determineShortType($v, $uses, $namespaceName); + if (null === $shortTokens) { + return $v; + } + + return implode('', array_map( + static fn (Token $token) => $token->getContent(), + $shortTokens + )); + }, explode('|', $matches[4]))); + }, $phpDocContent); + + if ($phpDocContentNew !== $phpDocContent) { + $tokens[$index] = new Token([T_DOC_COMMENT, $phpDocContentNew]); + } + } + + /** + * @param array $uses + */ + private function fixExtendsImplements(Tokens $tokens, int $index, array $uses, string $namespaceName): void + { + // We handle `extends` and `implements` with similar logic, but we need to exit the loop under different conditions. + $isExtends = $tokens[$index]->equals([T_EXTENDS]); + $index = $tokens->getNextMeaningfulToken($index); + + $typeStartIndex = null; + $typeEndIndex = null; + + while (true) { + if ($tokens[$index]->equalsAny([',', '{', [T_IMPLEMENTS]])) { + if (null !== $typeStartIndex) { + $index += $this->shortenClassIfPossible($tokens, $typeStartIndex, $typeEndIndex, $uses, $namespaceName); + } + $typeStartIndex = null; - foreach ($types as $typeName => [$startIndex, $endIndex]) { - if ((new TypeAnalysis($typeName))->isReservedType()) { - return; + if ($tokens[$index]->equalsAny($isExtends ? [[T_IMPLEMENTS], '{'] : ['{'])) { + break; + } + } else { + if (null === $typeStartIndex) { + $typeStartIndex = $index; + } + $typeEndIndex = $index; } - $withLeadingBackslash = str_starts_with($typeName, '\\'); - if ($withLeadingBackslash) { - $typeName = substr($typeName, 1); + $index = $tokens->getNextMeaningfulToken($index); + } + } + + /** + * @param array $uses + */ + private function fixCatch(Tokens $tokens, int $index, array $uses, string $namespaceName): void + { + $index = $tokens->getNextMeaningfulToken($index); // '(' + $index = $tokens->getNextMeaningfulToken($index); // first part of first exception class to be caught + + $typeStartIndex = null; + $typeEndIndex = null; + + while (true) { + if ($tokens[$index]->equalsAny([')', [T_VARIABLE], [CT::T_TYPE_ALTERNATION]])) { + if (null === $typeStartIndex) { + break; + } + + $index += $this->shortenClassIfPossible($tokens, $typeStartIndex, $typeEndIndex, $uses, $namespaceName); + $typeStartIndex = null; + + if ($tokens[$index]->equals(')')) { + break; + } + } else { + if (null === $typeStartIndex) { + $typeStartIndex = $index; + } + $typeEndIndex = $index; } - $typeNameLower = strtolower($typeName); - if (isset($uses[$typeNameLower]) && ($withLeadingBackslash || '' === $namespaceName)) { - // if the type without leading "\" equals any of the full "uses" long names, it can be replaced with the short one - $tokens->overrideRange($startIndex, $endIndex, $this->namespacedStringToTokens($uses[$typeNameLower])); + $index = $tokens->getNextMeaningfulToken($index); + } + } + + /** + * @param array $uses + */ + private function fixAttribute(Tokens $tokens, int $index, array $uses, string $namespaceName): void + { + $attributeAnalysis = AttributeAnalyzer::collectOne($tokens, $index); - continue; + foreach ($attributeAnalysis->getAttributes() as $attribute) { + $index = $attribute['start']; + while ($tokens[$index]->equalsAny([[T_STRING], [T_NS_SEPARATOR]])) { + $index = $tokens->getPrevMeaningfulToken($index); + } + $this->fixNextName($tokens, $index, $uses, $namespaceName); + } + } + + /** + * @param array $uses + */ + private function fixPrevName(Tokens $tokens, int $index, array $uses, string $namespaceName): void + { + $typeStartIndex = null; + $typeEndIndex = null; + + while (true) { + $index = $tokens->getPrevMeaningfulToken($index); + if ($tokens[$index]->isObjectOperator()) { + break; } - if ('' === $namespaceName) { - foreach ($uses as $useShortName) { - if (strtolower($useShortName) === $typeNameLower) { - continue 2; - } + if ($tokens[$index]->equalsAny([[T_STRING], [T_NS_SEPARATOR]])) { + $typeStartIndex = $index; + if (null === $typeEndIndex) { + $typeEndIndex = $index; + } + } else { + if (null !== $typeEndIndex) { + $index += $this->shortenClassIfPossible($tokens, $typeStartIndex, $typeEndIndex, $uses, $namespaceName); } - // if we are in the global namespace and the type is not imported, - // we enforce/remove leading backslash (depending on the configuration) - if (true === $this->configuration['leading_backslash_in_global_namespace']) { - if (!$withLeadingBackslash && !isset($uses[$typeNameLower])) { - $tokens->overrideRange( - $startIndex, - $endIndex, - $this->namespacedStringToTokens($typeName, true) - ); - } - } else { - $tokens->overrideRange($startIndex, $endIndex, $this->namespacedStringToTokens($typeName)); + break; + } + } + } + + /** + * @param array $uses + */ + private function fixNextName(Tokens $tokens, int $index, array $uses, string $namespaceName): void + { + $typeStartIndex = null; + $typeEndIndex = null; + + while (true) { + $index = $tokens->getNextMeaningfulToken($index); + + if ($tokens[$index]->equalsAny([[T_STRING], [T_NS_SEPARATOR]])) { + if (null === $typeStartIndex) { + $typeStartIndex = $index; } - } elseif (!str_contains($typeName, '\\')) { - // If we're NOT in the global namespace, there's no related import, - // AND used type is from global namespace, then it can't be shortened. - continue; - } elseif ($typeNameLower !== $namespaceName && str_starts_with($typeNameLower, $namespaceName.'\\')) { - // if the type starts with namespace and the type is not the same as the namespace it can be shortened - $typeNameShort = substr($typeName, $namespaceNameLength + 1); - - // if short names are the same, but long one are different then it cannot be shortened - foreach ($uses as $useLongName => $useShortName) { - if ( - strtolower($typeNameShort) === strtolower($useShortName) - && strtolower($typeName) !== strtolower($useLongName) - ) { - continue 2; - } + $typeEndIndex = $index; + } else { + if (null !== $typeStartIndex) { + $index += $this->shortenClassIfPossible($tokens, $typeStartIndex, $typeEndIndex, $uses, $namespaceName); } - $tokens->overrideRange($startIndex, $endIndex, $this->namespacedStringToTokens($typeNameShort)); + break; + } + } + } + + /** + * @param array $uses + */ + private function shortenClassIfPossible(Tokens $tokens, int $typeStartIndex, int $typeEndIndex, array $uses, string $namespaceName): int + { + $content = $tokens->generatePartialCode($typeStartIndex, $typeEndIndex); + $newTokens = $this->determineShortType($content, $uses, $namespaceName); + if (null === $newTokens) { + return 0; + } + + $tokens->overrideRange($typeStartIndex, $typeEndIndex, $newTokens); + + return \count($newTokens) - ($typeEndIndex - $typeStartIndex) - 1; + } + + /** + * @param array $uses + */ + private function replaceByShortType(Tokens $tokens, TypeAnalysis $type, array $uses, string $namespaceName): void + { + $typeStartIndex = $type->getStartIndex(); + + if ($tokens[$typeStartIndex]->isGivenKind(CT::T_NULLABLE_TYPE)) { + $typeStartIndex = $tokens->getNextMeaningfulToken($typeStartIndex); + } + + $types = $this->getTypes($tokens, $typeStartIndex, $type->getEndIndex()); + + foreach ($types as [$startIndex, $endIndex]) { + $content = $tokens->generatePartialCode($startIndex, $endIndex); + $newTokens = $this->determineShortType($content, $uses, $namespaceName); + if (null !== $newTokens) { + $tokens->overrideRange($startIndex, $endIndex, $newTokens); } } } /** - * @return iterable + * Determines short type based on FQCN, current namespace and imports (`use` declarations). + * + * @param array $uses + * + * @return null|list + */ + private function determineShortType(string $typeName, array $uses, string $namespaceName): ?array + { + if (null !== $this->discoveredSymbols) { + if (!$this->isReservedIdentifier($typeName)) { + $this->discoveredSymbols['class'][] = $typeName; + } + + return null; + } + + $fqcn = $this->resolveSymbol($typeName, $uses, $namespaceName); + $shortenedType = $this->shortenSymbol($fqcn, $uses, $namespaceName); + if ($shortenedType === $typeName) { + return null; + } + + return $this->namespacedStringToTokens($shortenedType); + } + + /** + * @return iterable */ private function getTypes(Tokens $tokens, int $index, int $endIndex): iterable { $skipNextYield = false; $typeStartIndex = $typeEndIndex = null; - $type = null; while (true) { if ($tokens[$index]->isGivenKind(CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_OPEN)) { $index = $tokens->getNextMeaningfulToken($index); $typeStartIndex = $typeEndIndex = null; - $type = null; continue; } @@ -244,19 +847,17 @@ private function getTypes(Tokens $tokens, int $index, int $endIndex): iterable if (!$skipNextYield && null !== $typeStartIndex) { $origCount = \count($tokens); - yield $type => [$typeStartIndex, $typeEndIndex]; + yield [$typeStartIndex, $typeEndIndex]; $endIndex += \count($tokens) - $origCount; // type tokens were possibly updated, restart type match $skipNextYield = true; $index = $typeEndIndex = $typeStartIndex; - $type = null; } else { $skipNextYield = false; $index = $tokens->getNextMeaningfulToken($index); $typeStartIndex = $typeEndIndex = null; - $type = null; } if ($index > $endIndex) { @@ -268,25 +869,23 @@ private function getTypes(Tokens $tokens, int $index, int $endIndex): iterable if (null === $typeStartIndex) { $typeStartIndex = $index; - $type = ''; } - $typeEndIndex = $index; - $type .= $tokens[$index]->getContent(); $index = $tokens->getNextMeaningfulToken($index); } } /** - * @return Token[] + * @return list */ - private function namespacedStringToTokens(string $input, bool $withLeadingBackslash = false): array + private function namespacedStringToTokens(string $input): array { $tokens = []; - if ($withLeadingBackslash) { + if (str_starts_with($input, '\\')) { $tokens[] = new Token([T_NS_SEPARATOR, '\\']); + $input = substr($input, 1); } $parts = explode('\\', $input); @@ -300,4 +899,13 @@ private function namespacedStringToTokens(string $input, bool $withLeadingBacksl return $tokens; } + + /** + * We need to create import processor dynamically (not in costructor), because actual whitespace configuration + * is set later, not when fixer's instance is created. + */ + private function createImportProcessor(): ImportProcessor + { + return new ImportProcessor($this->whitespacesConfig); + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GlobalNamespaceImportFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GlobalNamespaceImportFixer.php index adda9828..73389d43 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GlobalNamespaceImportFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GlobalNamespaceImportFixer.php @@ -31,6 +31,7 @@ use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\NamespaceUsesAnalyzer; use PhpCsFixer\Tokenizer\CT; +use PhpCsFixer\Tokenizer\Processor\ImportProcessor; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; use PhpCsFixer\Tokenizer\TokensAnalyzer; @@ -40,6 +41,15 @@ */ final class GlobalNamespaceImportFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { + private ImportProcessor $importProcessor; + + public function __construct() + { + parent::__construct(); + + $this->importProcessor = new ImportProcessor($this->whitespacesConfig); + } + public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( @@ -90,7 +100,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run before NoUnusedImportsFixer, OrderedImportsFixer. + * Must run before NoUnusedImportsFixer, OrderedImportsFixer, StatementIndentationFixer. * Must run after NativeConstantInvocationFixer, NativeFunctionInvocationFixer. */ public function getPriority(): int @@ -136,10 +146,16 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $this->fullyQualifyClasses($tokens, $useDeclarations); } - $newImports = array_filter($newImports); - if (\count($newImports) > 0) { - $this->insertImports($tokens, $newImports, $useDeclarations); + if (\count($useDeclarations) > 0) { + $useDeclaration = end($useDeclarations); + $atIndex = $useDeclaration->getEndIndex() + 1; + } else { + $namespace = $tokens->getNamespaceDeclarations()[0]; + $atIndex = $namespace->getEndIndex() + 1; + } + + $this->importProcessor->insertImports($tokens, $newImports, $atIndex); } } @@ -162,7 +178,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn } /** - * @param NamespaceUseAnalysis[] $useDeclarations + * @param list $useDeclarations * * @return array */ @@ -233,7 +249,7 @@ private function importConstants(Tokens $tokens, array $useDeclarations): array } /** - * @param NamespaceUseAnalysis[] $useDeclarations + * @param list $useDeclarations * * @return array */ @@ -283,7 +299,7 @@ private function importFunctions(Tokens $tokens, array $useDeclarations): array } /** - * @param NamespaceUseAnalysis[] $useDeclarations + * @param list $useDeclarations * * @return array */ @@ -291,7 +307,7 @@ private function importClasses(Tokens $tokens, array $useDeclarations): array { [$global, $other] = $this->filterUseDeclarations($useDeclarations, static fn (NamespaceUseAnalysis $declaration): bool => $declaration->isClass(), false); - /** @var DocBlock[] $docBlocks */ + /** @var array $docBlocks */ $docBlocks = []; // find class declarations and class usages in docblocks @@ -391,22 +407,24 @@ private function importClasses(Tokens $tokens, array $useDeclarations): array } } - return $imports + $this->prepareImports($tokens, $indices, $global, $other, false); + return array_merge($imports, $this->prepareImports($tokens, $indices, $global, $other, false)); } /** * Removes the leading slash at the given indices (when the name is not already used). * - * @param int[] $indices - * @param array $other + * @param list $indices + * @param array $global + * @param array $other * - * @return array array keys contain the names that must be imported + * @return array array keys contain the names that must be imported */ private function prepareImports(Tokens $tokens, array $indices, array $global, array $other, bool $caseSensitive): array { $imports = []; foreach ($indices as $index) { + /** @var class-string $name */ $name = $tokens[$index]->getContent(); $checkName = $caseSensitive ? $name : strtolower($name); @@ -427,50 +445,7 @@ private function prepareImports(Tokens $tokens, array $indices, array $global, a } /** - * @param NamespaceUseAnalysis[] $useDeclarations - */ - private function insertImports(Tokens $tokens, array $imports, array $useDeclarations): void - { - if (\count($useDeclarations) > 0) { - $useDeclaration = end($useDeclarations); - $index = $useDeclaration->getEndIndex() + 1; - } else { - $namespace = $tokens->getNamespaceDeclarations()[0]; - $index = $namespace->getEndIndex() + 1; - } - - $lineEnding = $this->whitespacesConfig->getLineEnding(); - - if (!$tokens[$index]->isWhitespace() || !str_contains($tokens[$index]->getContent(), "\n")) { - $tokens->insertAt($index, new Token([T_WHITESPACE, $lineEnding])); - } - - foreach ($imports as $type => $typeImports) { - foreach ($typeImports as $name) { - $items = [ - new Token([T_WHITESPACE, $lineEnding]), - new Token([T_USE, 'use']), - new Token([T_WHITESPACE, ' ']), - ]; - - if ('const' === $type) { - $items[] = new Token([CT::T_CONST_IMPORT, 'const']); - $items[] = new Token([T_WHITESPACE, ' ']); - } elseif ('function' === $type) { - $items[] = new Token([CT::T_FUNCTION_IMPORT, 'function']); - $items[] = new Token([T_WHITESPACE, ' ']); - } - - $items[] = new Token([T_STRING, $name]); - $items[] = new Token(';'); - - $tokens->insertAt($index, $items); - } - } - } - - /** - * @param NamespaceUseAnalysis[] $useDeclarations + * @param list $useDeclarations */ private function fullyQualifyConstants(Tokens $tokens, array $useDeclarations): void { @@ -480,7 +455,7 @@ private function fullyQualifyConstants(Tokens $tokens, array $useDeclarations): [$global] = $this->filterUseDeclarations($useDeclarations, static fn (NamespaceUseAnalysis $declaration): bool => $declaration->isConstant() && !$declaration->isAliased(), true); - if (!$global) { + if ([] === $global) { return; } @@ -510,7 +485,7 @@ private function fullyQualifyConstants(Tokens $tokens, array $useDeclarations): } /** - * @param NamespaceUseAnalysis[] $useDeclarations + * @param list $useDeclarations */ private function fullyQualifyFunctions(Tokens $tokens, array $useDeclarations): void { @@ -520,7 +495,7 @@ private function fullyQualifyFunctions(Tokens $tokens, array $useDeclarations): [$global] = $this->filterUseDeclarations($useDeclarations, static fn (NamespaceUseAnalysis $declaration): bool => $declaration->isFunction() && !$declaration->isAliased(), false); - if (!$global) { + if ([] === $global) { return; } @@ -550,7 +525,7 @@ private function fullyQualifyFunctions(Tokens $tokens, array $useDeclarations): } /** - * @param NamespaceUseAnalysis[] $useDeclarations + * @param list $useDeclarations */ private function fullyQualifyClasses(Tokens $tokens, array $useDeclarations): void { @@ -560,7 +535,7 @@ private function fullyQualifyClasses(Tokens $tokens, array $useDeclarations): vo [$global] = $this->filterUseDeclarations($useDeclarations, static fn (NamespaceUseAnalysis $declaration): bool => $declaration->isClass() && !$declaration->isAliased(), false); - if (!$global) { + if ([] === $global) { return; } @@ -608,7 +583,9 @@ private function fullyQualifyClasses(Tokens $tokens, array $useDeclarations): vo } /** - * @param NamespaceUseAnalysis[] $declarations + * @param list $declarations + * + * @return array{0: array, 1: array} */ private function filterUseDeclarations(array $declarations, callable $callback, bool $caseSensitive): array { @@ -706,7 +683,7 @@ private function traverseDocBlockTypes(DocBlock $doc, callable $callback): bool foreach ($types as $i => $fullType) { $newFullType = $fullType; - Preg::matchAll('/[\\\\\w]+/', $fullType, $matches, PREG_OFFSET_CAPTURE); + Preg::matchAll('/[\\\\\w]+(?![\\\\\w:])/', $fullType, $matches, PREG_OFFSET_CAPTURE); foreach (array_reverse($matches[0]) as [$type, $offset]) { $newType = $callback($type); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GroupImportFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GroupImportFixer.php index 00ee24b8..0bb9e85f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GroupImportFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/GroupImportFixer.php @@ -61,7 +61,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void /** * Gets namespace use analyzers with same namespaces. * - * @return NamespaceUseAnalysis[] + * @return list */ private function getSameNamespaces(Tokens $tokens): array { @@ -89,16 +89,16 @@ private function getSameNamespaces(Tokens $tokens): array $namespaceA = $this->getNamespaceNameWithSlash($a); $namespaceB = $this->getNamespaceNameWithSlash($b); - $namespaceDifference = \strlen($namespaceA) - \strlen($namespaceB); + $namespaceDifference = \strlen($namespaceA) <=> \strlen($namespaceB); - return 0 !== $namespaceDifference ? $namespaceDifference : strcmp($a->getFullName(), $b->getFullName()); + return 0 !== $namespaceDifference ? $namespaceDifference : $a->getFullName() <=> $b->getFullName(); }); return $sameNamespaceAnalysis; } /** - * @param NamespaceUseAnalysis[] $statements + * @param list $statements */ private function removeSingleUseStatements(array $statements, Tokens $tokens): void { @@ -129,7 +129,7 @@ private function removeSingleUseStatements(array $statements, Tokens $tokens): v } /** - * @param NamespaceUseAnalysis[] $statements + * @param list $statements */ private function addGroupUseStatements(array $statements, Tokens $tokens): void { @@ -143,7 +143,7 @@ private function addGroupUseStatements(array $statements, Tokens $tokens): void $tokens, $insertIndex, $useDeclaration, - $this->getNamespaceNameWithSlash($currentUseDeclaration) + rtrim($this->getNamespaceNameWithSlash($currentUseDeclaration), '\\') ); } else { $newTokens = [ @@ -225,7 +225,7 @@ private function createNewGroup(Tokens $tokens, int $insertIndex, NamespaceUseAn $newTokens[] = new Token([T_WHITESPACE, ' ']); } - $namespaceParts = array_filter(explode('\\', $currentNamespace)); + $namespaceParts = explode('\\', $currentNamespace); foreach ($namespaceParts as $part) { $newTokens[] = new Token([T_STRING, $part]); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/NoUnusedImportsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/NoUnusedImportsFixer.php index 898865d9..379396d9 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/NoUnusedImportsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/NoUnusedImportsFixer.php @@ -59,7 +59,7 @@ public function isCandidate(Tokens $tokens): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - $useDeclarations = (new NamespaceUsesAnalyzer())->getDeclarationsFromTokens($tokens); + $useDeclarations = (new NamespaceUsesAnalyzer())->getDeclarationsFromTokens($tokens, true); if (0 === \count($useDeclarations)) { return; @@ -175,7 +175,7 @@ private function isImportUsed(Tokens $tokens, NamespaceAnalysis $namespace, Name if ($token->isComment() && Preg::match( - '/(?getShortName().'(?![[:alnum:]])/i', + '/(?getShortName().'(?![[:alnum:]])/i', $token->getContent() ) ) { @@ -186,15 +186,23 @@ private function isImportUsed(Tokens $tokens, NamespaceAnalysis $namespace, Name return false; } - private function removeUseDeclaration(Tokens $tokens, NamespaceUseAnalysis $useDeclaration): void - { - for ($index = $useDeclaration->getEndIndex() - 1; $index >= $useDeclaration->getStartIndex(); --$index) { + private function removeUseDeclaration( + Tokens $tokens, + NamespaceUseAnalysis $useDeclaration, + bool $forceCompleteRemoval = false + ): void { + [$start, $end] = ($useDeclaration->isInMulti() && !$forceCompleteRemoval) + ? [$useDeclaration->getChunkStartIndex(), $useDeclaration->getChunkEndIndex()] + : [$useDeclaration->getStartIndex(), $useDeclaration->getEndIndex()]; + $loopStartIndex = $useDeclaration->isInMulti() || $forceCompleteRemoval ? $end : $end - 1; + + for ($index = $loopStartIndex; $index >= $start; --$index) { if ($tokens[$index]->isComment()) { continue; } if (!$tokens[$index]->isWhitespace() || !str_contains($tokens[$index]->getContent(), "\n")) { - $tokens->clearTokenAndMergeSurroundingWhitespace($index); + $tokens->clearAt($index); continue; } @@ -210,12 +218,109 @@ private function removeUseDeclaration(Tokens $tokens, NamespaceUseAnalysis $useD } } + // For multi-use import statements the tokens containing FQN were already removed in the loop above. + // We need to clean up tokens around the ex-chunk to keep the correct syntax and achieve proper formatting. + if (!$forceCompleteRemoval && $useDeclaration->isInMulti()) { + $this->cleanUpAfterImportChunkRemoval($tokens, $useDeclaration); + + return; + } + if ($tokens[$useDeclaration->getEndIndex()]->equals(';')) { // do not remove `? >` $tokens->clearAt($useDeclaration->getEndIndex()); } - // remove white space above and below where the `use` statement was + $this->cleanUpSurroundingNewLines($tokens, $useDeclaration); + } + + /** + * @param list $useDeclarations + */ + private function removeUsesInSameNamespace(Tokens $tokens, array $useDeclarations, NamespaceAnalysis $namespaceDeclaration): void + { + $namespace = $namespaceDeclaration->getFullName(); + $nsLength = \strlen($namespace.'\\'); + + foreach ($useDeclarations as $useDeclaration) { + if ($useDeclaration->isAliased()) { + continue; + } + + $useDeclarationFullName = ltrim($useDeclaration->getFullName(), '\\'); + + if (!str_starts_with($useDeclarationFullName, $namespace.'\\')) { + continue; + } + + $partName = substr($useDeclarationFullName, $nsLength); + + if (!str_contains($partName, '\\')) { + $this->removeUseDeclaration($tokens, $useDeclaration); + } + } + } + + private function cleanUpAfterImportChunkRemoval(Tokens $tokens, NamespaceUseAnalysis $useDeclaration): void + { + $beforeChunkIndex = $tokens->getPrevMeaningfulToken($useDeclaration->getChunkStartIndex()); + $afterChunkIndex = $tokens->getNextMeaningfulToken($useDeclaration->getChunkEndIndex()); + $hasNonEmptyTokenBefore = $this->scanForNonEmptyTokensUntilNewLineFound( + $tokens, + $afterChunkIndex, + -1 + ); + $hasNonEmptyTokenAfter = $this->scanForNonEmptyTokensUntilNewLineFound( + $tokens, + $afterChunkIndex, + 1 + ); + + // We don't want to merge consequent new lines with indentation (leading to e.g. `\n \n `), + // so it's safe to merge whitespace only if there is any non-empty token before or after the chunk. + $mergingSurroundingWhitespaceIsSafe = $hasNonEmptyTokenBefore[1] || $hasNonEmptyTokenAfter[1]; + $clearToken = static function (int $index) use ($tokens, $mergingSurroundingWhitespaceIsSafe): void { + if ($mergingSurroundingWhitespaceIsSafe) { + $tokens->clearTokenAndMergeSurroundingWhitespace($index); + } else { + $tokens->clearAt($index); + } + }; + + if ($tokens[$afterChunkIndex]->equals(',')) { + $clearToken($afterChunkIndex); + } elseif ($tokens[$beforeChunkIndex]->equals(',')) { + $clearToken($beforeChunkIndex); + } + + // Ensure there's a single space where applicable, otherwise no space (before comma, before closing brace) + for ($index = $beforeChunkIndex; $index <= $afterChunkIndex; ++$index) { + if (null === $tokens[$index]->getId() || !$tokens[$index]->isWhitespace(' ')) { + continue; + } + + $nextTokenIndex = $tokens->getNextMeaningfulToken($index); + if ( + $tokens[$nextTokenIndex]->equals(',') + || $tokens[$nextTokenIndex]->equals(';') + || $tokens[$nextTokenIndex]->isGivenKind([CT::T_GROUP_IMPORT_BRACE_CLOSE]) + ) { + $tokens->clearAt($index); + } else { + $tokens[$index] = new Token([T_WHITESPACE, ' ']); + } + + $prevTokenIndex = $tokens->getPrevMeaningfulToken($index); + if ($tokens[$prevTokenIndex]->isGivenKind([CT::T_GROUP_IMPORT_BRACE_OPEN])) { + $tokens->clearAt($index); + } + } + + $this->removeLineIfEmpty($tokens, $useDeclaration); + $this->removeImportStatementIfEmpty($tokens, $useDeclaration); + } + private function cleanUpSurroundingNewLines(Tokens $tokens, NamespaceUseAnalysis $useDeclaration): void + { $prevIndex = $useDeclaration->getStartIndex() - 1; $prevToken = $tokens[$prevIndex]; @@ -261,30 +366,90 @@ private function removeUseDeclaration(Tokens $tokens, NamespaceUseAnalysis $useD } } - /** - * @param list $useDeclarations - */ - private function removeUsesInSameNamespace(Tokens $tokens, array $useDeclarations, NamespaceAnalysis $namespaceDeclaration): void + private function removeImportStatementIfEmpty(Tokens $tokens, NamespaceUseAnalysis $useDeclaration): void { - $namespace = $namespaceDeclaration->getFullName(); - $nsLength = \strlen($namespace.'\\'); + // First we look for empty groups where all chunks were removed (`use Foo\{};`). + // We're only interested in ending brace if its index is between start and end of the import statement. + $endingBraceIndex = $tokens->getPrevTokenOfKind( + $useDeclaration->getEndIndex(), + [[CT::T_GROUP_IMPORT_BRACE_CLOSE]] + ); - foreach ($useDeclarations as $useDeclaration) { - if ($useDeclaration->isAliased()) { - continue; + if ($endingBraceIndex > $useDeclaration->getStartIndex()) { + $openingBraceIndex = $tokens->getPrevMeaningfulToken($endingBraceIndex); + + if ($tokens[$openingBraceIndex]->isGivenKind(CT::T_GROUP_IMPORT_BRACE_OPEN)) { + $this->removeUseDeclaration($tokens, $useDeclaration, true); } + } - $useDeclarationFullName = ltrim($useDeclaration->getFullName(), '\\'); + // Second we look for empty groups where all comma-separated chunks were removed (`use;`). + $beforeSemicolonIndex = $tokens->getPrevMeaningfulToken($useDeclaration->getEndIndex()); + if ( + $tokens[$beforeSemicolonIndex]->isGivenKind([T_USE]) + || \in_array($tokens[$beforeSemicolonIndex]->getContent(), ['function', 'const'], true) + ) { + $this->removeUseDeclaration($tokens, $useDeclaration, true); + } + } - if (!str_starts_with($useDeclarationFullName, $namespace.'\\')) { + private function removeLineIfEmpty(Tokens $tokens, NamespaceUseAnalysis $useAnalysis): void + { + if (!$useAnalysis->isInMulti()) { + return; + } + + $hasNonEmptyTokenBefore = $this->scanForNonEmptyTokensUntilNewLineFound( + $tokens, + $useAnalysis->getChunkStartIndex(), + -1 + ); + $hasNonEmptyTokenAfter = $this->scanForNonEmptyTokensUntilNewLineFound( + $tokens, + $useAnalysis->getChunkEndIndex(), + 1 + ); + + if ( + \is_int($hasNonEmptyTokenBefore[0]) + && !$hasNonEmptyTokenBefore[1] + && \is_int($hasNonEmptyTokenAfter[0]) + && !$hasNonEmptyTokenAfter[1] + ) { + $tokens->clearRange($hasNonEmptyTokenBefore[0], $hasNonEmptyTokenAfter[0] - 1); + } + } + + /** + * Returns tuple with the index of first token with whitespace containing new line char + * and a flag if any non-empty token was found along the way. + * + * @param -1|1 $direction + * + * @return array{0: null|int, 1: bool} + */ + private function scanForNonEmptyTokensUntilNewLineFound(Tokens $tokens, int $index, int $direction): array + { + $hasNonEmptyToken = false; + $newLineTokenIndex = null; + + // Iterate until we find new line OR we get out of $tokens bounds (next sibling index is `null`). + while (\is_int($index)) { + $index = $tokens->getNonEmptySibling($index, $direction); + + if (null === $index || null === $tokens[$index]->getId()) { continue; } - $partName = substr($useDeclarationFullName, $nsLength); + if (!$tokens[$index]->isWhitespace()) { + $hasNonEmptyToken = true; + } elseif (str_starts_with($tokens[$index]->getContent(), "\n")) { + $newLineTokenIndex = $index; - if (!str_contains($partName, '\\')) { - $this->removeUseDeclaration($tokens, $useDeclaration); + break; } } + + return [$newLineTokenIndex, $hasNonEmptyToken]; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/OrderedImportsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/OrderedImportsFixer.php index 436206a3..477a7729 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/OrderedImportsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/OrderedImportsFixer.php @@ -36,6 +36,14 @@ * @author Dariusz Rumiński * @author Darius Matulionis * @author Adriano Pilger + * + * @phpstan-type _UseImportInfo array{ + * namespace: non-empty-string, + * startIndex: int, + * endIndex: int, + * importType: self::IMPORT_TYPE_*, + * group: bool, + * } */ final class OrderedImportsFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { @@ -72,14 +80,14 @@ final class OrderedImportsFixer extends AbstractFixer implements ConfigurableFix /** * Array of supported sort types in configuration. * - * @var string[] + * @var list */ private const SUPPORTED_SORT_TYPES = [self::IMPORT_TYPE_CLASS, self::IMPORT_TYPE_CONST, self::IMPORT_TYPE_FUNCTION]; /** * Array of supported sort algorithms in configuration. * - * @var string[] + * @var list */ private const SUPPORTED_SORT_ALGORITHMS = [self::SORT_ALPHA, self::SORT_LENGTH, self::SORT_NONE]; @@ -175,7 +183,7 @@ public function getDefinition(): FixerDefinitionInterface * {@inheritdoc} * * Must run before BlankLineBetweenImportGroupsFixer. - * Must run after GlobalNamespaceImportFixer, NoLeadingImportSlashFixer. + * Must run after FullyQualifiedStrictTypesFixer, GlobalNamespaceImportFixer, NoLeadingImportSlashFixer. */ public function getPriority(): int { @@ -277,10 +285,8 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn /** * This method is used for sorting the uses in a namespace. * - * @param array $first - * @param array $second - * - * @internal + * @param _UseImportInfo $first + * @param _UseImportInfo $second */ private function sortAlphabetically(array $first, array $second): int { @@ -289,17 +295,15 @@ private function sortAlphabetically(array $first, array $second): int $secondNamespace = str_replace('\\', ' ', $this->prepareNamespace($second['namespace'])); return true === $this->configuration['case_sensitive'] - ? strcmp($firstNamespace, $secondNamespace) + ? $firstNamespace <=> $secondNamespace : strcasecmp($firstNamespace, $secondNamespace); } /** * This method is used for sorting the uses statements in a namespace by length. * - * @param array $first - * @param array $second - * - * @internal + * @param _UseImportInfo $first + * @param _UseImportInfo $second */ private function sortByLength(array $first, array $second): int { @@ -311,7 +315,7 @@ private function sortByLength(array $first, array $second): int if ($firstNamespaceLength === $secondNamespaceLength) { $sortResult = true === $this->configuration['case_sensitive'] - ? strcmp($firstNamespace, $secondNamespace) + ? $firstNamespace <=> $secondNamespace : strcasecmp($firstNamespace, $secondNamespace); } else { $sortResult = $firstNamespaceLength > $secondNamespaceLength ? 1 : -1; @@ -327,6 +331,8 @@ private function prepareNamespace(string $namespace): string /** * @param list $uses + * + * @return array */ private function getNewOrder(array $uses, Tokens $tokens): array { @@ -511,27 +517,9 @@ private function getNewOrder(array $uses, Tokens $tokens): array } /** - * @param array< - * int, - * array{ - * namespace: string, - * startIndex: int, - * endIndex: int, - * importType: string, - * group: bool, - * } - * > $indices + * @param array $indices * - * @return array< - * int, - * array{ - * namespace: string, - * startIndex: int, - * endIndex: int, - * importType: string, - * group: bool, - * } - * > + * @return array */ private function sortByAlgorithm(array $indices): array { @@ -545,13 +533,7 @@ private function sortByAlgorithm(array $indices): array } /** - * @param array $usesOrder + * @param array $usesOrder */ private function setNewOrder(Tokens $tokens, array $usesOrder): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleImportPerStatementFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleImportPerStatementFixer.php index 2ced868c..f10e93db 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleImportPerStatementFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Import/SingleImportPerStatementFixer.php @@ -84,7 +84,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $groupClose = $tokens->getPrevMeaningfulToken($endIndex); if ($tokens[$groupClose]->isGivenKind(CT::T_GROUP_IMPORT_BRACE_CLOSE)) { - if ($this->configuration['group_to_single_imports']) { + if (true === $this->configuration['group_to_single_imports']) { $this->fixGroupUse($tokens, $index, $endIndex); } } else { @@ -103,6 +103,9 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ]); } + /** + * @return array{string, ?int, int, string} + */ private function getGroupDeclaration(Tokens $tokens, int $index): array { $groupPrefix = ''; @@ -143,7 +146,7 @@ private function getGroupDeclaration(Tokens $tokens, int $index): array } /** - * @return string[] + * @return list */ private function getGroupStatements(Tokens $tokens, string $groupPrefix, int $groupOpenIndex, int $groupCloseIndex, string $comment): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordFixer.php new file mode 100644 index 00000000..b171e56b --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordFixer.php @@ -0,0 +1,100 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\LanguageConstruct; + +use PhpCsFixer\AbstractFixer; +use PhpCsFixer\Fixer\ExperimentalFixerInterface; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * @author Dariusz Rumiński + */ +final class ClassKeywordFixer extends AbstractFixer implements ExperimentalFixerInterface +{ + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'Converts FQCN strings to `*::class` keywords.', + [ + new CodeSample( + 'count() - 1; $index >= 0; --$index) { + $token = $tokens[$index]; + + if ($token->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) { + $name = substr($token->getContent(), 1, -1); + $name = ltrim($name, '\\'); + $name = str_replace('\\\\', '\\', $name); + + if ($this->exists($name)) { + $substitution = Tokens::fromCode("clearRange(0, 2); + $substitution->clearAt($substitution->getSize() - 1); + $substitution->clearEmptyTokens(); + + $tokens->clearAt($index); + $tokens->insertAt($index, $substitution); + } + } + } + } + + private function exists(string $name): bool + { + if (class_exists($name) || interface_exists($name) || trait_exists($name)) { + $rc = new \ReflectionClass($name); + + return $rc->getName() === $name; + } + + return false; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordRemoveFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordRemoveFixer.php index 29b4b6a6..3caf9f1b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordRemoveFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/ClassKeywordRemoveFixer.php @@ -32,7 +32,7 @@ final class ClassKeywordRemoveFixer extends AbstractFixer implements DeprecatedFixerInterface { /** - * @var string[] + * @var array */ private array $imports = []; @@ -188,7 +188,7 @@ private function replaceClassKeyword(Tokens $tokens, string $namespacePrefix, in $classStringArray = explode('\\', $classString); $namespaceToTest = $classStringArray[0]; - if (0 === strcmp($namespaceToTest, substr($import, -\strlen($namespaceToTest)))) { + if (0 === ($namespaceToTest <=> substr($import, -\strlen($namespaceToTest)))) { $classImport = $import; break; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php index 10e19180..e84bcb9d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveIssetsFixer.php @@ -104,7 +104,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param int[] $indices + * @param list $indices */ private function clearTokens(Tokens $tokens, array $indices): void { @@ -116,7 +116,7 @@ private function clearTokens(Tokens $tokens, array $indices): void /** * @param int $index of T_ISSET * - * @return int[] indices of meaningful tokens belonging to the isset statement + * @return list indices of meaningful tokens belonging to the isset statement */ private function getIssetInfo(Tokens $tokens, int $index): array { @@ -146,9 +146,9 @@ private function getIssetInfo(Tokens $tokens, int $index): array } /** - * @param int[] $indices + * @param list $indices * - * @return Token[] + * @return list */ private function getTokenClones(Tokens $tokens, array $indices): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveUnsetsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveUnsetsFixer.php index 6ec6b753..24f18958 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveUnsetsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/CombineConsecutiveUnsetsFixer.php @@ -92,7 +92,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param int[] $indices + * @param list $indices */ private function clearOffsetTokens(Tokens $tokens, int $offset, array $indices): void { @@ -112,7 +112,7 @@ private function clearOffsetTokens(Tokens $tokens, int $offset, array $indices): * * Or the index to where the method looked for a call. * - * @return int|int[] + * @return array{int, int, int, int}|int */ private function getPreviousUnsetCall(Tokens $tokens, int $index) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/DeclareEqualNormalizeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/DeclareEqualNormalizeFixer.php index 76b70a20..ae7c9ea4 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/DeclareEqualNormalizeFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/DeclareEqualNormalizeFixer.php @@ -30,18 +30,6 @@ */ final class DeclareEqualNormalizeFixer extends AbstractFixer implements ConfigurableFixerInterface { - /** - * @var string - */ - private $callback; - - public function configure(array $configuration): void - { - parent::configure($configuration); - - $this->callback = 'none' === $this->configuration['space'] ? 'removeWhitespaceAroundToken' : 'ensureWhitespaceAroundToken'; - } - public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( @@ -70,7 +58,6 @@ public function isCandidate(Tokens $tokens): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - $callback = $this->callback; for ($index = 0, $count = $tokens->count(); $index < $count - 6; ++$index) { if (!$tokens[$index]->isGivenKind(T_DECLARE)) { continue; @@ -81,7 +68,11 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void for ($i = $closeParenthesisIndex; $i > $openParenthesisIndex; --$i) { if ($tokens[$i]->equals('=')) { - $this->{$callback}($tokens, $i); + if ('none' === $this->configuration['space']) { + $this->removeWhitespaceAroundToken($tokens, $i); + } else { + $this->ensureWhitespaceAroundToken($tokens, $i); + } } } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/FunctionToConstantFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/FunctionToConstantFixer.php index 0c81c54d..fa4da76e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/FunctionToConstantFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/FunctionToConstantFixer.php @@ -31,12 +31,12 @@ final class FunctionToConstantFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var array + * @var array> */ private static $availableFunctions; /** - * @var array + * @var array> */ private array $functionsFixMap; @@ -49,7 +49,11 @@ public function __construct() new Token([T_DOUBLE_COLON, '::']), new Token([CT::T_CLASS_CONSTANT, 'class']), ], - 'get_class' => [new Token([T_CLASS_C, '__CLASS__'])], + 'get_class' => [ + new Token([T_STRING, 'self']), + new Token([T_DOUBLE_COLON, '::']), + new Token([CT::T_CLASS_CONSTANT, 'class']), + ], 'get_class_this' => [ new Token([T_STATIC, 'static']), new Token([T_DOUBLE_COLON, '::']), @@ -155,7 +159,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn } /** - * @param Token[] $replacements + * @param list $replacements */ private function fixFunctionCallToConstant(Tokens $tokens, int $index, int $braceOpenIndex, int $braceCloseIndex, array $replacements): void { @@ -167,7 +171,10 @@ private function fixFunctionCallToConstant(Tokens $tokens, int $index, int $brac $tokens->clearTokenAndMergeSurroundingWhitespace($i); } - if ($replacements[0]->isGivenKind([T_CLASS_C, T_STATIC])) { + if ( + $replacements[0]->isGivenKind([T_CLASS_C, T_STATIC]) + || ($replacements[0]->isGivenKind(T_STRING) && 'self' === $replacements[0]->getContent()) + ) { $prevIndex = $tokens->getPrevMeaningfulToken($index); $prevToken = $tokens[$prevIndex]; if ($prevToken->isGivenKind(T_NS_SEPARATOR)) { @@ -179,6 +186,9 @@ private function fixFunctionCallToConstant(Tokens $tokens, int $index, int $brac $tokens->insertAt($index, $replacements); } + /** + * @return ?array{int, int, list} + */ private function getReplaceCandidate( Tokens $tokens, FunctionsAnalyzer $functionAnalyzer, @@ -216,6 +226,9 @@ private function getReplaceCandidate( return $this->getReplacementTokenClones($lowerContent, $braceOpenIndex, $braceCloseIndex); } + /** + * @return ?array{int, int, list} + */ private function fixGetClassCall( Tokens $tokens, FunctionsAnalyzer $functionAnalyzer, @@ -267,12 +280,15 @@ private function fixGetClassCall( return null; } + /** + * @return array{int, int, list} + */ private function getReplacementTokenClones(string $lowerContent, int $braceOpenIndex, int $braceCloseIndex): array { - $clones = []; - foreach ($this->functionsFixMap[$lowerContent] as $token) { - $clones[] = clone $token; - } + $clones = array_map( + static fn (Token $token): Token => clone $token, + $this->functionsFixMap[$lowerContent], + ); return [ $braceOpenIndex, diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/NoUnsetOnPropertyFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/NoUnsetOnPropertyFixer.php index 15a151a1..c72a783a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/NoUnsetOnPropertyFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/NoUnsetOnPropertyFixer.php @@ -84,7 +84,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return array> + * @return list> */ private function getUnsetsInfo(Tokens $tokens, int $index): array { @@ -144,7 +144,7 @@ private function isProperty(Tokens $tokens, int $index, int $endIndex): bool } /** - * @param array> $unsetsInfo + * @param list> $unsetsInfo */ private function isAnyUnsetToTransform(array $unsetsInfo): bool { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/SingleSpaceAroundConstructFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/SingleSpaceAroundConstructFixer.php index 29d395f9..67da8784 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/SingleSpaceAroundConstructFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/LanguageConstruct/SingleSpaceAroundConstructFixer.php @@ -345,7 +345,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - if ($token->isGivenKind(T_CONST) && $this->isMultilineConstant($tokens, $index)) { + if ($token->isGivenKind(T_CONST) && $this->isMultilineCommaSeparatedConstant($tokens, $index)) { continue; } @@ -355,6 +355,23 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } } + if ($tokens[$whitespaceTokenIndex]->isWhitespace() && str_contains($tokens[$whitespaceTokenIndex]->getContent(), "\n")) { + $nextNextToken = $tokens[$whitespaceTokenIndex + 1]; + if (\defined('T_ATTRIBUTE')) { // @TODO: drop condition and else when PHP 8.0+ is required + if ($nextNextToken->isGivenKind(T_ATTRIBUTE)) { + continue; + } + } else { + if ($nextNextToken->isComment() && str_starts_with($nextNextToken->getContent(), '#[')) { + continue; + } + } + + if ($nextNextToken->isGivenKind(T_DOC_COMMENT)) { + continue; + } + } + $tokens->ensureWhitespaceAtIndex($whitespaceTokenIndex, 0, ' '); } } @@ -440,11 +457,27 @@ private function isMultilineExtendsOrImplementsWithMoreThanOneAncestor(Tokens $t return false; } - private function isMultilineConstant(Tokens $tokens, int $index): bool + private function isMultilineCommaSeparatedConstant(Tokens $tokens, int $constantIndex): bool { - $scopeEnd = $tokens->getNextTokenOfKind($index, [';', [T_CLOSE_TAG]]) - 1; - $hasMoreThanOneConstant = null !== $tokens->findSequence([new Token(',')], $index + 1, $scopeEnd); + $isMultilineConstant = false; + $hasMoreThanOneConstant = false; + $index = $constantIndex; + while (!$tokens[$index]->equalsAny([';', [T_CLOSE_TAG]])) { + ++$index; + + $isMultilineConstant = $isMultilineConstant || str_contains($tokens[$index]->getContent(), "\n"); + + if ($tokens[$index]->equals(',')) { + $hasMoreThanOneConstant = true; + } + + $blockType = Tokens::detectBlockType($tokens[$index]); + + if (null !== $blockType && true === $blockType['isStart']) { + $index = $tokens->findBlockEnd($blockType['type'], $index); + } + } - return $hasMoreThanOneConstant && $tokens->isPartialCodeMultiline($index, $scopeEnd); + return $hasMoreThanOneConstant && $isMultilineConstant; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ListNotation/ListSyntaxFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ListNotation/ListSyntaxFixer.php index f7f06bca..3bc18cea 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ListNotation/ListSyntaxFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ListNotation/ListSyntaxFixer.php @@ -69,7 +69,7 @@ public function getDefinition(): FixerDefinitionInterface */ public function getPriority(): int { - return 1; + return 2; } public function isCandidate(Tokens $tokens): bool diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/BlankLinesBeforeNamespaceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/BlankLinesBeforeNamespaceFixer.php index 162bc65f..4d2a78e7 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/BlankLinesBeforeNamespaceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/BlankLinesBeforeNamespaceFixer.php @@ -69,7 +69,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn (new FixerOptionBuilder('min_line_breaks', 'Minimum line breaks that should exist before namespace declaration.')) ->setAllowedTypes(['int']) ->setDefault(2) - ->setNormalizer(static function (Options $options, $value): int { + ->setNormalizer(static function (Options $options, int $value): int { if ($value < 0) { throw new InvalidFixerConfigurationException( (new self())->getName(), @@ -83,7 +83,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn (new FixerOptionBuilder('max_line_breaks', 'Maximum line breaks that should exist before namespace declaration.')) ->setAllowedTypes(['int']) ->setDefault(2) - ->setNormalizer(static function (Options $options, $value): int { + ->setNormalizer(static function (Options $options, int $value): int { if ($value < 0) { throw new InvalidFixerConfigurationException( (new self())->getName(), diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/CleanNamespaceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/CleanNamespaceFixer.php index f39ed81d..bb63adbd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/CleanNamespaceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/NamespaceNotation/CleanNamespaceFixer.php @@ -27,7 +27,7 @@ public function getDefinition(): FixerDefinitionInterface { $samples = []; - foreach (['namespace Foo \\ Bar;', 'echo foo /* comment */ \\ bar();'] as $sample) { + foreach (['namespace Foo \ Bar;', 'echo foo /* comment */ \ bar();'] as $sample) { $samples[] = new VersionSpecificCodeSample( " self::$replacements[$matches[0]] ?? $matches[0], $token->getContent(), -1, $count); - if ($count) { + if ($count > 0) { $tokens->offsetSet($index, new Token([$token->getId(), $replaced])); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/BinaryOperatorSpacesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/BinaryOperatorSpacesFixer.php index 3f95b189..3e7f59b8 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/BinaryOperatorSpacesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/BinaryOperatorSpacesFixer.php @@ -88,7 +88,7 @@ final class BinaryOperatorSpacesFixer extends AbstractFixer implements Configura public const ALIGN_PLACEHOLDER = "\x2 ALIGNABLE%d \x3"; /** - * @var string[] + * @var list */ private const SUPPORTED_OPERATORS = [ '=', @@ -150,7 +150,7 @@ final class BinaryOperatorSpacesFixer extends AbstractFixer implements Configura private int $currentLevel; /** - * @var array + * @var list */ private static array $allowedValues = [ self::ALIGN, diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/ConcatSpaceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/ConcatSpaceFixer.php index 8c452604..c499e628 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/ConcatSpaceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/ConcatSpaceFixer.php @@ -30,22 +30,6 @@ */ final class ConcatSpaceFixer extends AbstractFixer implements ConfigurableFixerInterface { - /** - * @var null|string - */ - private $fixCallback; - - public function configure(array $configuration): void - { - parent::configure($configuration); - - if ('one' === $this->configuration['spacing']) { - $this->fixCallback = 'fixConcatenationToSingleSpace'; - } else { - $this->fixCallback = 'fixConcatenationToNoSpace'; - } - } - public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( @@ -83,10 +67,13 @@ public function isCandidate(Tokens $tokens): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - $callBack = $this->fixCallback; for ($index = $tokens->count() - 1; $index >= 0; --$index) { if ($tokens[$index]->equals('.')) { - $this->{$callBack}($tokens, $index); + if ('one' === $this->configuration['spacing']) { + $this->fixConcatenationToSingleSpace($tokens, $index); + } else { + $this->fixConcatenationToNoSpace($tokens, $index); + } } } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/LongToShorthandOperatorFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/LongToShorthandOperatorFixer.php index ca57caa4..fad4c48a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/LongToShorthandOperatorFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/LongToShorthandOperatorFixer.php @@ -40,7 +40,7 @@ final class LongToShorthandOperatorFixer extends AbstractShortOperatorFixer ]; /** - * @var string[] + * @var list */ private array $operatorTypes; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NewWithParenthesesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NewWithParenthesesFixer.php index 9c9d7aab..81f95ece 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NewWithParenthesesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NewWithParenthesesFixer.php @@ -131,7 +131,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void if ($tokens[$nextIndex]->isGivenKind(T_CLASS)) { $nextIndex = $tokens->getNextMeaningfulToken($nextIndex); - if ($this->configuration['anonymous_class']) { + if (true === $this->configuration['anonymous_class']) { $this->ensureParenthesesAt($tokens, $nextIndex); } else { $this->ensureNoParenthesesAt($tokens, $nextIndex); @@ -147,7 +147,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $nextIndex = $tokens->getNextMeaningfulToken($nextIndex); } - if ($this->configuration['named_class']) { + if (true === $this->configuration['named_class']) { $this->ensureParenthesesAt($tokens, $nextIndex); } else { $this->ensureNoParenthesesAt($tokens, $nextIndex); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoSpaceAroundDoubleColonFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoSpaceAroundDoubleColonFixer.php index ddf0c2df..d897fff5 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoSpaceAroundDoubleColonFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoSpaceAroundDoubleColonFixer.php @@ -30,6 +30,16 @@ public function getDefinition(): FixerDefinitionInterface ); } + /** + * {@inheritdoc} + * + * Must run before MethodChainingIndentationFixer. + */ + public function getPriority(): int + { + return 1; + } + public function isCandidate(Tokens $tokens): bool { return $tokens->isTokenKindFound(T_DOUBLE_COLON); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoUselessConcatOperatorFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoUselessConcatOperatorFixer.php index 5f834da3..79c35e7c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoUselessConcatOperatorFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/NoUselessConcatOperatorFixer.php @@ -26,6 +26,13 @@ use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; +/** + * @phpstan-type _ConcatOperandType array{ + * start: int, + * end: int, + * type: self::STR_*, + * } + */ final class NoUselessConcatOperatorFixer extends AbstractFixer implements ConfigurableFixerInterface { private const STR_DOUBLE_QUOTE = 0; @@ -47,7 +54,7 @@ public function getDefinition(): FixerDefinitionInterface * {@inheritdoc} * * Must run before DateTimeCreateFromFormatCallFixer, EregToPregFixer, PhpUnitDedicateAssertInternalTypeFixer, RegularCallableCallFixer, SetTypeToCastFixer. - * Must run after NoBinaryStringFixer, SingleQuoteFixer. + * Must run after ExplicitStringVariableFixer, NoBinaryStringFixer, SingleQuoteFixer. */ public function getPriority(): int { @@ -105,16 +112,8 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn } /** - * @param array{ - * start: int, - * end: int, - * type: self::STR_*, - * } $firstOperand - * @param array{ - * start: int, - * end: int, - * type: self::STR_*, - * } $secondOperand + * @param _ConcatOperandType $firstOperand + * @param _ConcatOperandType $secondOperand */ private function fixConcatOperation(Tokens $tokens, array $firstOperand, int $concatIndex, array $secondOperand): void { @@ -124,13 +123,17 @@ private function fixConcatOperation(Tokens $tokens, array $firstOperand, int $co (self::STR_DOUBLE_QUOTE === $firstOperand['type'] && self::STR_DOUBLE_QUOTE === $secondOperand['type']) || (self::STR_SINGLE_QUOTE === $firstOperand['type'] && self::STR_SINGLE_QUOTE === $secondOperand['type']) ) { - $this->mergeContantEscapedStringOperands($tokens, $firstOperand, $concatIndex, $secondOperand); + $this->mergeConstantEscapedStringOperands($tokens, $firstOperand, $concatIndex, $secondOperand); return; } if (self::STR_DOUBLE_QUOTE_VAR === $firstOperand['type'] && self::STR_DOUBLE_QUOTE_VAR === $secondOperand['type']) { - $this->mergeContantEscapedStringVarOperands($tokens, $firstOperand, $concatIndex, $secondOperand); + if ($this->operandsCanNotBeMerged($tokens, $firstOperand, $secondOperand)) { + return; + } + + $this->mergeConstantEscapedStringVarOperands($tokens, $firstOperand, $concatIndex, $secondOperand); return; } @@ -146,12 +149,16 @@ private function fixConcatOperation(Tokens $tokens, array $firstOperand, int $co [$operand1, $operand2] = $operandPair; if (self::STR_DOUBLE_QUOTE_VAR === $operand1['type'] && self::STR_DOUBLE_QUOTE === $operand2['type']) { - $this->mergeContantEscapedStringVarOperands($tokens, $firstOperand, $concatIndex, $secondOperand); + if ($this->operandsCanNotBeMerged($tokens, $operand1, $operand2)) { + return; + } + + $this->mergeConstantEscapedStringVarOperands($tokens, $firstOperand, $concatIndex, $secondOperand); return; } - if (!$this->configuration['juggle_simple_strings']) { + if (false === $this->configuration['juggle_simple_strings']) { continue; } @@ -159,7 +166,7 @@ private function fixConcatOperation(Tokens $tokens, array $firstOperand, int $co $operantContent = $tokens[$operand2['start']]->getContent(); if ($this->isSimpleQuotedStringContent($operantContent)) { - $this->mergeContantEscapedStringOperands($tokens, $firstOperand, $concatIndex, $secondOperand); + $this->mergeConstantEscapedStringOperands($tokens, $firstOperand, $concatIndex, $secondOperand); } return; @@ -169,7 +176,11 @@ private function fixConcatOperation(Tokens $tokens, array $firstOperand, int $co $operantContent = $tokens[$operand2['start']]->getContent(); if ($this->isSimpleQuotedStringContent($operantContent)) { - $this->mergeContantEscapedStringVarOperands($tokens, $firstOperand, $concatIndex, $secondOperand); + if ($this->operandsCanNotBeMerged($tokens, $operand1, $operand2)) { + return; + } + + $this->mergeConstantEscapedStringVarOperands($tokens, $firstOperand, $concatIndex, $secondOperand); } return; @@ -180,11 +191,7 @@ private function fixConcatOperation(Tokens $tokens, array $firstOperand, int $co /** * @param -1|1 $direction * - * @return null|array{ - * start: int, - * end: int, - * type: self::STR_*, - * } + * @return null|_ConcatOperandType */ private function getConcatOperandType(Tokens $tokens, int $index, int $direction): ?array { @@ -216,18 +223,10 @@ private function getConcatOperandType(Tokens $tokens, int $index, int $direction } /** - * @param array{ - * start: int, - * end: int, - * type: self::STR_*, - * } $firstOperand - * @param array{ - * start: int, - * end: int, - * type: self::STR_*, - * } $secondOperand + * @param _ConcatOperandType $firstOperand + * @param _ConcatOperandType $secondOperand */ - private function mergeContantEscapedStringOperands( + private function mergeConstantEscapedStringOperands( Tokens $tokens, array $firstOperand, int $concatOperatorIndex, @@ -244,29 +243,21 @@ private function mergeContantEscapedStringOperands( ], ); - $tokens->clearTokenAndMergeSurroundingWhitespace($secondOperand['start']); $this->clearConcatAndAround($tokens, $concatOperatorIndex); + $tokens->clearTokenAndMergeSurroundingWhitespace($secondOperand['start']); } /** - * @param array{ - * start: int, - * end: int, - * type: self::STR_*, - * } $firstOperand - * @param array{ - * start: int, - * end: int, - * type: self::STR_*, - * } $secondOperand + * @param _ConcatOperandType $firstOperand + * @param _ConcatOperandType $secondOperand */ - private function mergeContantEscapedStringVarOperands( + private function mergeConstantEscapedStringVarOperands( Tokens $tokens, array $firstOperand, int $concatOperatorIndex, array $secondOperand ): void { - // build uo the new content + // build up the new content $newContent = ''; foreach ([$firstOperand, $secondOperand] as $operant) { @@ -336,4 +327,36 @@ private function containsLinebreak(Tokens $tokens, int $startIndex, int $endInde return false; } + + /** + * @param _ConcatOperandType $firstOperand + * @param _ConcatOperandType $secondOperand + */ + private function operandsCanNotBeMerged(Tokens $tokens, array $firstOperand, array $secondOperand): bool + { + // If the first operand does not end with a variable, no variables would be broken by concatenation. + if (self::STR_DOUBLE_QUOTE_VAR !== $firstOperand['type']) { + return false; + } + if (!$tokens[$firstOperand['end'] - 1]->isGivenKind(T_VARIABLE)) { + return false; + } + + $allowedPatternsForSecondOperand = [ + '/^\s.*/', // e.g. " foo", ' bar', " $baz" + '/^-(?!\>)/', // e.g. "-foo", '-bar', "-$baz" + ]; + + // If the first operand ends with a variable, the second operand should match one of the allowed patterns. + // Otherwise, the concatenation can break a variable in the first operand. + foreach ($allowedPatternsForSecondOperand as $allowedPattern) { + $secondOperandInnerContent = substr($tokens->generatePartialCode($secondOperand['start'], $secondOperand['end']), 1, -1); + + if (Preg::match($allowedPattern, $secondOperandInnerContent)) { + return false; + } + } + + return true; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/OperatorLinebreakFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/OperatorLinebreakFixer.php index ad6887e7..a73a28c4 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/OperatorLinebreakFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/OperatorLinebreakFixer.php @@ -24,10 +24,9 @@ use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Preg; use PhpCsFixer\Tokenizer\Analyzer\AlternativeSyntaxAnalyzer; -use PhpCsFixer\Tokenizer\Analyzer\Analysis\SwitchAnalysis; -use PhpCsFixer\Tokenizer\Analyzer\ControlCaseStructuresAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\GotoLabelAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\ReferenceAnalyzer; +use PhpCsFixer\Tokenizer\Analyzer\SwitchAnalyzer; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; @@ -41,7 +40,7 @@ final class OperatorLinebreakFixer extends AbstractFixer implements Configurable private string $position = 'beginning'; /** - * @var array|string> + * @var list */ private array $operators = []; @@ -106,8 +105,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $gotoLabelAnalyzer = new GotoLabelAnalyzer(); $alternativeSyntaxAnalyzer = new AlternativeSyntaxAnalyzer(); - $excludedIndices = $this->getExcludedIndices($tokens); - $index = $tokens->count(); while ($index > 1) { --$index; @@ -128,7 +125,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - if (\in_array($index, $excludedIndices, true)) { + if (SwitchAnalyzer::belongsToSwitch($tokens, $index)) { continue; } @@ -147,32 +144,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * Currently only colons from "switch". - * - * @return int[] - */ - private function getExcludedIndices(Tokens $tokens): array - { - $colonIndices = []; - - /** @var SwitchAnalysis $analysis */ - foreach (ControlCaseStructuresAnalyzer::findControlStructures($tokens, [T_SWITCH]) as $analysis) { - foreach ($analysis->getCases() as $case) { - $colonIndices[] = $case->getColonIndex(); - } - - $defaultAnalysis = $analysis->getDefaultAnalysis(); - - if (null !== $defaultAnalysis) { - $colonIndices[] = $defaultAnalysis->getColonIndex(); - } - } - - return $colonIndices; - } - - /** - * @param int[] $operatorIndices + * @param non-empty-list $operatorIndices */ private function fixOperatorLinebreak(Tokens $tokens, array $operatorIndices): void { @@ -204,7 +176,7 @@ private function fixOperatorLinebreak(Tokens $tokens, array $operatorIndices): v } /** - * @param int[] $operatorIndices + * @param non-empty-list $operatorIndices */ private function fixMoveToTheBeginning(Tokens $tokens, array $operatorIndices): void { @@ -229,7 +201,7 @@ private function fixMoveToTheBeginning(Tokens $tokens, array $operatorIndices): } /** - * @param int[] $operatorIndices + * @param non-empty-list $operatorIndices */ private function fixMoveToTheEnd(Tokens $tokens, array $operatorIndices): void { @@ -254,9 +226,9 @@ private function fixMoveToTheEnd(Tokens $tokens, array $operatorIndices): void } /** - * @param int[] $indices + * @param list $indices * - * @return Token[] + * @return list */ private function getReplacementsAndClear(Tokens $tokens, array $indices, int $direction): array { @@ -287,6 +259,9 @@ private function isMultiline(Tokens $tokens, int $indexStart, int $indexEnd): bo return false; } + /** + * @return list + */ private static function getNonBooleanOperators(): array { return array_merge( diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryOperatorSpacesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryOperatorSpacesFixer.php index 1e6e0eb6..758c7939 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryOperatorSpacesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryOperatorSpacesFixer.php @@ -19,9 +19,8 @@ use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Tokenizer\Analyzer\AlternativeSyntaxAnalyzer; -use PhpCsFixer\Tokenizer\Analyzer\Analysis\SwitchAnalysis; -use PhpCsFixer\Tokenizer\Analyzer\ControlCaseStructuresAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\GotoLabelAnalyzer; +use PhpCsFixer\Tokenizer\Analyzer\SwitchAnalyzer; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; @@ -45,7 +44,7 @@ public function getDefinition(): FixerDefinitionInterface */ public function getPriority(): int { - return 0; + return 1; } public function isCandidate(Tokens $tokens): bool @@ -58,14 +57,13 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $alternativeSyntaxAnalyzer = new AlternativeSyntaxAnalyzer(); $gotoLabelAnalyzer = new GotoLabelAnalyzer(); $ternaryOperatorIndices = []; - $excludedIndices = $this->getColonIndicesForSwitch($tokens); foreach ($tokens as $index => $token) { if (!$token->equalsAny(['?', ':'])) { continue; } - if (\in_array($index, $excludedIndices, true)) { + if (SwitchAnalyzer::belongsToSwitch($tokens, $index)) { continue; } @@ -114,29 +112,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } } - /** - * @return int[] - */ - private function getColonIndicesForSwitch(Tokens $tokens): array - { - $colonIndices = []; - - /** @var SwitchAnalysis $analysis */ - foreach (ControlCaseStructuresAnalyzer::findControlStructures($tokens, [T_SWITCH]) as $analysis) { - foreach ($analysis->getCases() as $case) { - $colonIndices[] = $case->getColonIndex(); - } - - $defaultAnalysis = $analysis->getDefaultAnalysis(); - - if (null !== $defaultAnalysis) { - $colonIndices[] = $defaultAnalysis->getColonIndex(); - } - } - - return $colonIndices; - } - private function ensureWhitespaceExistence(Tokens $tokens, int $index, bool $after): void { if ($tokens[$index]->isWhitespace()) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryToElvisOperatorFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryToElvisOperatorFixer.php index 4cbae0a1..191d8bf9 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryToElvisOperatorFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/TernaryToElvisOperatorFixer.php @@ -80,7 +80,7 @@ public function getDefinition(): FixerDefinitionInterface */ public function getPriority(): int { - return 1; + return 2; } public function isCandidate(Tokens $tokens): bool @@ -95,8 +95,6 @@ public function isRisky(): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - $blockEdgeDefinitions = Tokens::getBlockEdgeDefinitions(); - for ($index = \count($tokens) - 5; $index > 1; --$index) { if (!$tokens[$index]->equals('?')) { continue; @@ -110,7 +108,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // get and check what is before the `?` operator - $beforeOperator = $this->getBeforeOperator($tokens, $index, $blockEdgeDefinitions); + $beforeOperator = $this->getBeforeOperator($tokens, $index); if (null === $beforeOperator) { continue; // contains something we cannot fix because of priorities @@ -129,10 +127,11 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return null|array{start: int, end: int} null if contains ++/-- operator + * @return ?array{start: int, end: int} null if contains ++/-- operator */ - private function getBeforeOperator(Tokens $tokens, int $index, array $blockEdgeDefinitions): ?array + private function getBeforeOperator(Tokens $tokens, int $index): ?array { + $blockEdgeDefinitions = Tokens::getBlockEdgeDefinitions(); $index = $tokens->getPrevMeaningfulToken($index); $before = ['end' => $index]; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/UnaryOperatorSpacesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/UnaryOperatorSpacesFixer.php index 05953717..873e9326 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/UnaryOperatorSpacesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/UnaryOperatorSpacesFixer.php @@ -15,6 +15,10 @@ namespace PhpCsFixer\Fixer\Operator; use PhpCsFixer\AbstractFixer; +use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; +use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; @@ -22,17 +26,30 @@ use PhpCsFixer\Tokenizer\TokensAnalyzer; /** - * Fixer for rules defined in PSR12 ¶6.1. - * * @author Gregor Harlan + * @author Dariusz Rumiński */ -final class UnaryOperatorSpacesFixer extends AbstractFixer +final class UnaryOperatorSpacesFixer extends AbstractFixer implements ConfigurableFixerInterface { public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( 'Unary operators should be placed adjacent to their operands.', - [new CodeSample(" false] + ), + new CodeSample( + ' true] + ), + ] ); } @@ -51,11 +68,25 @@ public function isCandidate(Tokens $tokens): bool return true; } + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface + { + return new FixerConfigurationResolver([ + (new FixerOptionBuilder('only_dec_inc', 'Limit to increment and decrement operators.')) + ->setAllowedTypes(['bool']) + ->setDefault(false) + ->getOption(), + ]); + } + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { $tokensAnalyzer = new TokensAnalyzer($tokens); for ($index = $tokens->count() - 1; $index >= 0; --$index) { + if (true === $this->configuration['only_dec_inc'] && !$tokens[$index]->isGivenKind([T_DEC, T_INC])) { + continue; + } + if ($tokensAnalyzer->isUnarySuccessorOperator($index)) { if (!$tokens[$tokens->getPrevNonWhitespace($index)]->isComment()) { $tokens->removeLeadingWhitespace($index); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/BlankLineAfterOpeningTagFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/BlankLineAfterOpeningTagFixer.php index 8c8dbad7..d4af8196 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/BlankLineAfterOpeningTagFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/BlankLineAfterOpeningTagFixer.php @@ -48,23 +48,16 @@ public function getPriority(): int public function isCandidate(Tokens $tokens): bool { - return $tokens->isTokenKindFound(T_OPEN_TAG); + return $tokens->isMonolithicPhp() && !$tokens->isTokenKindFound(T_OPEN_TAG_WITH_ECHO); } protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { $lineEnding = $this->whitespacesConfig->getLineEnding(); - // ignore files with short open tag and ignore non-monolithic files - if (!$tokens[0]->isGivenKind(T_OPEN_TAG) || !$tokens->isMonolithicPhp()) { - return; - } - $newlineFound = false; - - /** @var Token $token */ foreach ($tokens as $token) { - if ($token->isWhitespace() && str_contains($token->getContent(), "\n")) { + if (($token->isWhitespace() || $token->isGivenKind(T_OPEN_TAG)) && str_contains($token->getContent(), "\n")) { $newlineFound = true; break; @@ -76,17 +69,19 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void return; } - $token = $tokens[0]; + $openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0; + $token = $tokens[$openTagIndex]; if (!str_contains($token->getContent(), "\n")) { - $tokens[0] = new Token([$token->getId(), rtrim($token->getContent()).$lineEnding]); + $tokens[$openTagIndex] = new Token([$token->getId(), rtrim($token->getContent()).$lineEnding]); } - if (!str_contains($tokens[1]->getContent(), "\n")) { - if ($tokens[1]->isWhitespace()) { - $tokens[1] = new Token([T_WHITESPACE, $lineEnding.$tokens[1]->getContent()]); + $newLineIndex = $openTagIndex + 1; + if (isset($tokens[$newLineIndex]) && !str_contains($tokens[$newLineIndex]->getContent(), "\n")) { + if ($tokens[$newLineIndex]->isWhitespace()) { + $tokens[$newLineIndex] = new Token([T_WHITESPACE, $lineEnding.$tokens[$newLineIndex]->getContent()]); } else { - $tokens->insertAt(1, new Token([T_WHITESPACE, $lineEnding])); + $tokens->insertAt($newLineIndex, new Token([T_WHITESPACE, $lineEnding])); } } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/EchoTagSyntaxFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/EchoTagSyntaxFixer.php index ed09a485..7c61daad 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/EchoTagSyntaxFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/EchoTagSyntaxFixer.php @@ -226,7 +226,7 @@ private function isComplexCode(Tokens $tokens, int $index): bool /** * Builds the list of tokens that replace a long echo sequence. * - * @return Token[] + * @return list */ private function buildLongToShortTokens(Tokens $tokens, int $openTagIndex, int $echoTagIndex): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/FullOpeningTagFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/FullOpeningTagFixer.php index 61186ccd..bf6c1313 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/FullOpeningTagFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/FullOpeningTagFixer.php @@ -62,7 +62,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // replace all isTokenKindFound(T_OPEN_TAG); + return $tokens->isMonolithicPhp() && !$tokens->isTokenKindFound(T_OPEN_TAG_WITH_ECHO); } protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - // ignore files with short open tag and ignore non-monolithic files - if (!$tokens[0]->isGivenKind(T_OPEN_TAG) || !$tokens->isMonolithicPhp()) { - return; - } + $openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0; // ignore if linebreak already present - if (str_contains($tokens[0]->getContent(), "\n")) { + if (str_contains($tokens[$openTagIndex]->getContent(), "\n")) { return; } $newlineFound = false; foreach ($tokens as $token) { - if ($token->isWhitespace() && str_contains($token->getContent(), "\n")) { + if (($token->isWhitespace() || $token->isGivenKind(T_OPEN_TAG)) && str_contains($token->getContent(), "\n")) { $newlineFound = true; break; @@ -66,6 +63,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void return; } - $tokens[0] = new Token([T_OPEN_TAG, rtrim($tokens[0]->getContent()).$this->whitespacesConfig->getLineEnding()]); + $tokens[$openTagIndex] = new Token([T_OPEN_TAG, rtrim($tokens[$openTagIndex]->getContent()).$this->whitespacesConfig->getLineEnding()]); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/NoClosingTagFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/NoClosingTagFixer.php index c6e611b3..14c40c03 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/NoClosingTagFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpTag/NoClosingTagFixer.php @@ -38,17 +38,13 @@ public function getDefinition(): FixerDefinitionInterface public function isCandidate(Tokens $tokens): bool { - return $tokens->isTokenKindFound(T_CLOSE_TAG); + return \count($tokens) >= 2 && $tokens->isMonolithicPhp() && $tokens->isTokenKindFound(T_CLOSE_TAG); } protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - if (\count($tokens) < 2 || !$tokens->isMonolithicPhp() || !$tokens->isTokenKindFound(T_CLOSE_TAG)) { - return; - } - $closeTags = $tokens->findGivenKind(T_CLOSE_TAG); - $index = key($closeTags); + $index = array_key_first($closeTags); if (isset($tokens[$index - 1]) && $tokens[$index - 1]->isWhitespace()) { $tokens->clearAt($index - 1); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php new file mode 100644 index 00000000..6433110c --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitAttributesFixer.php @@ -0,0 +1,516 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\PhpUnit; + +use PhpCsFixer\DocBlock\Annotation; +use PhpCsFixer\DocBlock\DocBlock; +use PhpCsFixer\Fixer\AbstractPhpUnitFixer; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\FixerDefinition\VersionSpecification; +use PhpCsFixer\FixerDefinition\VersionSpecificCodeSample; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\CT; +use PhpCsFixer\Tokenizer\Processor\ImportProcessor; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * @author Kuba Werłos + */ +final class PhpUnitAttributesFixer extends AbstractPhpUnitFixer +{ + /** @var array */ + private array $fixingMap; + + public function __construct() + { + parent::__construct(); + $this->prepareFixingMap(); + } + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'PHPUnit attributes must be used over their respective PHPDoc-based annotations.', + [ + new VersionSpecificCodeSample( + <<<'PHP' + = 8_00_00 && parent::isCandidate($tokens); + } + + /** + * {@inheritdoc} + * + * Must run before FullyQualifiedStrictTypesFixer, PhpdocSeparationFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer. + */ + public function getPriority(): int + { + return 8; + } + + protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $endIndex): void + { + $classIndex = $tokens->getPrevTokenOfKind($startIndex, [[T_CLASS]]); + $docBlockIndex = $this->getDocBlockIndex($tokens, $classIndex); + if ($tokens[$docBlockIndex]->isGivenKind(T_DOC_COMMENT)) { + $startIndex = $docBlockIndex; + } + + for ($index = $endIndex; $index >= $startIndex; --$index) { + if (!$tokens[$index]->isGivenKind(T_DOC_COMMENT)) { + continue; + } + + $targetIndex = $tokens->getTokenNotOfKindSibling( + $index, + 1, + [[T_ABSTRACT], [T_COMMENT], [T_FINAL], [T_FUNCTION], [T_PRIVATE], [T_PROTECTED], [T_PUBLIC], [T_STATIC], [T_WHITESPACE]], + ); + $annotationScope = $tokens[$targetIndex]->isGivenKind(T_CLASS) ? 'class' : 'method'; + + $docBlock = new DocBlock($tokens[$index]->getContent()); + + foreach (array_reverse($docBlock->getAnnotations()) as $annotation) { + $annotationName = $annotation->getTag()->getName(); + + if (!isset($this->fixingMap[$annotationName])) { + continue; + } + if (!self::shouldBeFixed($annotationName, $annotationScope)) { + continue; + } + + /** @phpstan-ignore-next-line */ + $tokensToInsert = self::{$this->fixingMap[$annotationName]}($tokens, $index, $annotation); + + if ([] === $tokensToInsert) { + continue; + } + + $tokens->insertSlices([$index + 1 => $tokensToInsert]); + $annotation->remove(); + } + + if ('' === $docBlock->getContent()) { + $tokens->clearTokenAndMergeSurroundingWhitespace($index); + } else { + $tokens[$index] = new Token([T_DOC_COMMENT, $docBlock->getContent()]); + } + } + } + + private function prepareFixingMap(): void + { + // annotations that map to attribute without parameters + foreach ([ + 'after', + 'afterClass', + 'before', + 'beforeClass', + 'coversNothing', + 'doesNotPerformAssertions', + 'large', + 'medium', + 'runInSeparateProcess', + 'runTestsInSeparateProcesses', + 'small', + 'test', + 'preCondition', + 'postCondition', + ] as $annotation) { + $this->fixingMap[$annotation] = 'fixWithoutParameters'; + } + + // annotations that map to attribute with single string value + foreach (['group', 'testDox', 'ticket'] as $annotation) { + $this->fixingMap[$annotation] = 'fixWithSingleStringValue'; + } + + // annotations that map from 'enabled'/'disabled' value to attribute with boolean value + foreach (['backupGlobals', 'backupStaticAttributes', 'preserveGlobalState'] as $annotation) { + $this->fixingMap[$annotation] = 'fixWithEnabledDisabledValue'; + } + + // annotations that has custom mapping function + $this->fixingMap['covers'] = 'fixCovers'; + $this->fixingMap['dataProvider'] = 'fixDataProvider'; + $this->fixingMap['depends'] = 'fixDepends'; + $this->fixingMap['requires'] = 'fixRequires'; + $this->fixingMap['testWith'] = 'fixTestWith'; + $this->fixingMap['uses'] = 'fixUses'; + } + + private static function shouldBeFixed(string $annotationName, string $annotationScope): bool + { + if ( + 'method' === $annotationScope + && \in_array($annotationName, ['covers', 'large', 'medium', 'runTestsInSeparateProcesses', 'small', 'uses'], true) + ) { + return false; + } + + if ( + 'class' === $annotationScope + && \in_array($annotationName, ['after', 'afterClass', 'before', 'beforeClass', 'dataProvider', 'depends', 'postCondition', 'preCondition', 'runInSeparateProcess', 'test', 'testWith'], true) + ) { + return false; + } + + return true; + } + + /** + * @return list + */ + private static function fixWithoutParameters(Tokens $tokens, int $index, Annotation $annotation): array + { + return self::createAttributeTokens($tokens, $index, self::getAttributeNameForAnnotation($annotation)); + } + + /** + * @return list + */ + private static function fixWithSingleStringValue(Tokens $tokens, int $index, Annotation $annotation): array + { + Preg::match( + sprintf('/@%s\s+(.*\S)(?:\R|\s*\*+\/$)/', $annotation->getTag()->getName()), + $annotation->getContent(), + $matches, + ); + if (!isset($matches[1])) { + return []; + } + + return self::createAttributeTokens( + $tokens, + $index, + self::getAttributeNameForAnnotation($annotation), + self::createEscapedStringToken($matches[1]), + ); + } + + /** + * @return list + */ + private static function fixWithEnabledDisabledValue(Tokens $tokens, int $index, Annotation $annotation): array + { + $matches = self::getMatches($annotation); + if (!isset($matches[1])) { + return []; + } + + return self::createAttributeTokens( + $tokens, + $index, + self::getAttributeNameForAnnotation($annotation), + new Token([T_STRING, isset($matches[1]) && 'enabled' === $matches[1] ? 'true' : 'false']), + ); + } + + /** + * @return list + */ + private static function fixCovers(Tokens $tokens, int $index, Annotation $annotation): array + { + $matches = self::getMatches($annotation); + + if (str_starts_with($matches[1], '::')) { + return self::createAttributeTokens($tokens, $index, 'CoversFunction', self::createEscapedStringToken(substr($matches[1], 2))); + } + if (!str_contains($matches[1], '::')) { + return self::createAttributeTokens( + $tokens, + $index, + 'CoversClass', + ...self::toClassConstant($matches[1]), + ); + } + + return []; + } + + /** + * @return list + */ + private static function fixDataProvider(Tokens $tokens, int $index, Annotation $annotation): array + { + $matches = self::getMatches($annotation); + if (!isset($matches[1])) { + return []; + } + + if (str_contains($matches[1], '::')) { + [$class, $method] = explode('::', $matches[1]); + + return self::createAttributeTokens( + $tokens, + $index, + 'DataProviderExternal', + ...[ + ...self::toClassConstant($class), + new Token(','), + new Token([T_WHITESPACE, ' ']), + self::createEscapedStringToken($method), + ], + ); + } + + return self::createAttributeTokens($tokens, $index, 'DataProvider', self::createEscapedStringToken($matches[1])); + } + + /** + * @return list + */ + private static function fixDepends(Tokens $tokens, int $index, Annotation $annotation): array + { + $matches = self::getMatches($annotation); + if (!isset($matches[1])) { + return []; + } + + $nameSuffix = ''; + $depended = $matches[1]; + if (isset($matches[2])) { + if ('clone' === $matches[1]) { + $nameSuffix = 'UsingDeepClone'; + $depended = $matches[2]; + } elseif ('shallowClone' === $matches[1]) { + $nameSuffix = 'UsingShallowClone'; + $depended = $matches[2]; + } + } + + $class = null; + $method = $depended; + if (str_contains($depended, '::')) { + [$class, $method] = explode('::', $depended); + if ('class' === $method) { + $method = null; + $nameSuffix = '' === $nameSuffix ? 'OnClass' : ('OnClass'.$nameSuffix); + } else { + $nameSuffix = ('External'.$nameSuffix); + } + } + + $attributeTokens = []; + if (null !== $class) { + $attributeTokens = self::toClassConstant($class); + } + if (null !== $method) { + if ([] !== $attributeTokens) { + $attributeTokens[] = new Token(','); + $attributeTokens[] = new Token([T_WHITESPACE, ' ']); + } + $attributeTokens[] = self::createEscapedStringToken($method); + } + + return self::createAttributeTokens($tokens, $index, 'Depends'.$nameSuffix, ...$attributeTokens); + } + + /** + * @return list + */ + private static function fixRequires(Tokens $tokens, int $index, Annotation $annotation): array + { + $matches = self::getMatches($annotation); + + $map = [ + 'extension' => 'RequiresPhpExtension', + 'function' => 'RequiresFunction', + 'PHP' => 'RequiresPhp', + 'PHPUnit' => 'RequiresPhpunit', + 'OS' => 'RequiresOperatingSystem', + 'OSFAMILY' => 'RequiresOperatingSystemFamily', + 'setting' => 'RequiresSetting', + ]; + + if (!isset($matches[2]) || !isset($map[$matches[1]])) { + return []; + } + + $attributeName = $map[$matches[1]]; + + if ('RequiresFunction' === $attributeName && str_contains($matches[2], '::')) { + [$class, $method] = explode('::', $matches[2]); + $attributeName = 'RequiresMethod'; + $attributeTokens = [...self::toClassConstant($class), + new Token(','), + new Token([T_WHITESPACE, ' ']), + self::createEscapedStringToken($method), + ]; + } elseif ('RequiresPhp' === $attributeName && isset($matches[3])) { + $attributeTokens = [self::createEscapedStringToken($matches[2].' '.$matches[3])]; + } else { + $attributeTokens = [self::createEscapedStringToken($matches[2])]; + } + + if (isset($matches[3]) && 'RequiresPhp' !== $attributeName) { + $attributeTokens[] = new Token(','); + $attributeTokens[] = new Token([T_WHITESPACE, ' ']); + $attributeTokens[] = self::createEscapedStringToken($matches[3]); + } + + return self::createAttributeTokens($tokens, $index, $attributeName, ...$attributeTokens); + } + + /** + * @return list + */ + private static function fixTestWith(Tokens $tokens, int $index, Annotation $annotation): array + { + $content = $annotation->getContent(); + $content = Preg::replace('/@testWith\s+/', '', $content); + $content = Preg::replace('/(^|\R)\s+\**\s*/', "\n", $content); + $content = trim($content); + if ('' === $content) { + return []; + } + + $attributeTokens = []; + foreach (explode("\n", $content) as $json) { + $attributeTokens = array_merge( + $attributeTokens, + self::createAttributeTokens($tokens, $index, 'TestWithJson', self::createEscapedStringToken($json)), + ); + } + + return $attributeTokens; + } + + /** + * @return list + */ + private static function fixUses(Tokens $tokens, int $index, Annotation $annotation): array + { + $matches = self::getMatches($annotation); + if (!isset($matches[1])) { + return []; + } + + if (str_starts_with($matches[1], '::')) { + $attributeName = 'UsesFunction'; + $attributeTokens = [self::createEscapedStringToken(substr($matches[1], 2))]; + } elseif (Preg::match('/^[a-zA-Z\d\\\]+$/', $matches[1])) { + $attributeName = 'UsesClass'; + $attributeTokens = self::toClassConstant($matches[1]); + } else { + return []; + } + + return self::createAttributeTokens($tokens, $index, $attributeName, ...$attributeTokens); + } + + /** + * @return list + */ + private static function getMatches(Annotation $annotation): array + { + Preg::match( + sprintf('/@%s\s+(\S+)(?:\s+(\S+))?(?:\s+(.+\S))?\s*(?:\R|\*+\/$)/', $annotation->getTag()->getName()), + $annotation->getContent(), + $matches, + ); + + \assert(array_is_list($matches)); // preg_match matches is not well typed, it depends on used regex, let's assure the type to instruct SCA + + return $matches; + } + + private static function getAttributeNameForAnnotation(Annotation $annotation): string + { + $annotationName = $annotation->getTag()->getName(); + + return 'backupStaticAttributes' === $annotationName + ? 'BackupStaticProperties' + : ucfirst($annotationName); + } + + /** + * @return list + */ + private static function createAttributeTokens( + Tokens $tokens, + int $index, + string $className, + Token ...$attributeTokens + ): array { + if ([] !== $attributeTokens) { + $attributeTokens = [ + new Token('('), + ...$attributeTokens, + new Token(')'), + ]; + } + + return [ + clone $tokens[$index + 1], + new Token([T_ATTRIBUTE, '#[']), + new Token([T_NS_SEPARATOR, '\\']), + new Token([T_STRING, 'PHPUnit']), + new Token([T_NS_SEPARATOR, '\\']), + new Token([T_STRING, 'Framework']), + new Token([T_NS_SEPARATOR, '\\']), + new Token([T_STRING, 'Attributes']), + new Token([T_NS_SEPARATOR, '\\']), + new Token([T_STRING, $className]), + ...$attributeTokens, + new Token([CT::T_ATTRIBUTE_CLOSE, ']']), + ]; + } + + /** + * @param class-string $name + * + * @return list + */ + private static function toClassConstant(string $name): array + { + return [ + ...ImportProcessor::tokenizeName($name), + new Token([T_DOUBLE_COLON, '::']), + new Token([CT::T_CLASS_CONSTANT, 'class']), + ]; + } + + private static function createEscapedStringToken(string $value): Token + { + return new Token([T_CONSTANT_ENCAPSED_STRING, "'".str_replace("'", "\\'", $value)."'"]); + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php index a3b8cf7e..4e76f3bf 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitConstructFixer.php @@ -32,16 +32,6 @@ */ final class PhpUnitConstructFixer extends AbstractPhpUnitFixer implements ConfigurableFixerInterface { - /** - * @var array - */ - private static array $assertionFixers = [ - 'assertSame' => 'fixAssertPositive', - 'assertEquals' => 'fixAssertPositive', - 'assertNotEquals' => 'fixAssertNegative', - 'assertNotSame' => 'fixAssertNegative', - ]; - public function isRisky(): bool { return true; @@ -93,6 +83,10 @@ public function getPriority(): int return -8; } + /** + * @uses fixAssertNegative() + * @uses fixAssertPositive() + */ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $endIndex): void { // no assertions to be fixed - fast return @@ -101,10 +95,13 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en } foreach ($this->configuration['assertions'] as $assertionMethod) { - $assertionFixer = self::$assertionFixers[$assertionMethod]; - for ($index = $startIndex; $index < $endIndex; ++$index) { - $index = $this->{$assertionFixer}($tokens, $index, $assertionMethod); + $index = \call_user_func_array( + \in_array($assertionMethod, ['assertSame', 'assertEquals'], true) + ? [$this, 'fixAssertPositive'] + : [$this, 'fixAssertNegative'], + [$tokens, $index, $assertionMethod] + ); if (null === $index) { break; @@ -115,16 +112,18 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { + $assertMethods = [ + 'assertEquals', + 'assertSame', + 'assertNotEquals', + 'assertNotSame', + ]; + return new FixerConfigurationResolver([ (new FixerOptionBuilder('assertions', 'List of assertion methods to fix.')) ->setAllowedTypes(['array']) - ->setAllowedValues([new AllowedValueSubset(array_keys(self::$assertionFixers))]) - ->setDefault([ - 'assertEquals', - 'assertSame', - 'assertNotEquals', - 'assertNotSame', - ]) + ->setAllowedValues([new AllowedValueSubset($assertMethods)]) + ->setDefault($assertMethods) ->getOption(), ]); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php index c42123b8..ae69b579 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderNameFixer.php @@ -101,7 +101,17 @@ public function dataProviderUsedAsSecondInTest() {} ); } - public function getConfigurationDefinition(): FixerConfigurationResolverInterface + public function getPriority(): int + { + return 0; + } + + public function isRisky(): bool + { + return true; + } + + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { return new FixerConfigurationResolver([ (new FixerOptionBuilder('prefix', 'Prefix that replaces "test".')) @@ -115,16 +125,6 @@ public function getConfigurationDefinition(): FixerConfigurationResolverInterfac ]); } - public function getPriority(): int - { - return 0; - } - - public function isRisky(): bool - { - return true; - } - protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $endIndex): void { $dataProviderAnalyzer = new DataProviderAnalyzer(); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderStaticFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderStaticFixer.php index 3d4786b7..70fb1d5f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderStaticFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDataProviderStaticFixer.php @@ -113,10 +113,12 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en if (null !== $methodStartIndex) { $methodEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $methodStartIndex); - if (!$this->configuration['force'] && null !== $tokens->findSequence([[T_VARIABLE, '$this']], $methodStartIndex, $methodEndIndex)) { + if (false === $this->configuration['force'] && null !== $tokens->findSequence([[T_VARIABLE, '$this']], $methodStartIndex, $methodEndIndex)) { continue; } } + + /** @var int $functionIndex */ $functionIndex = $tokens->getPrevTokenOfKind($dataProviderDefinitionIndex->getNameIndex(), [[T_FUNCTION]]); $methodAttributes = $tokensAnalyzer->getMethodAttributes($functionIndex); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDedicateAssertFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDedicateAssertFixer.php index ed599f5f..c65dd239 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDedicateAssertFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitDedicateAssertFixer.php @@ -34,7 +34,7 @@ final class PhpUnitDedicateAssertFixer extends AbstractPhpUnitFixer implements ConfigurableFixerInterface { /** - * @var array|true> + * @var array */ private static array $fixMap = [ 'array_key_exists' => [ @@ -109,7 +109,7 @@ final class PhpUnitDedicateAssertFixer extends AbstractPhpUnitFixer implements C ]; /** - * @var string[] + * @var list */ private array $functions = []; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitFqcnAnnotationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitFqcnAnnotationFixer.php index 65ae1ada..46bb9a7d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitFqcnAnnotationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitFqcnAnnotationFixer.php @@ -77,7 +77,7 @@ private function fixPhpUnitClass(Tokens $tokens, int $startIndex, int $endIndex) if ($tokens[$index]->isGivenKind(T_DOC_COMMENT)) { $tokens[$index] = new Token([T_DOC_COMMENT, Preg::replace( '~^(\s*\*\s*@(?:expectedException|covers|coversDefaultClass|uses)\h+)(?!(?:self|static)::)(\w.*)$~m', - '$1\\\\$2', + '$1\\\$2', $tokens[$index]->getContent() )]); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitInternalClassFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitInternalClassFixer.php index 6d89deb5..a156ea40 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitInternalClassFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitInternalClassFixer.php @@ -77,11 +77,12 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en return; } - $this->ensureIsDockBlockWithAnnotation( + $this->ensureIsDocBlockWithAnnotation( $tokens, $classIndex, 'internal', - ['internal'] + ['internal'], + [], ); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitMethodCasingFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitMethodCasingFixer.php index 04a3e5f7..c742c2d1 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitMethodCasingFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitMethodCasingFixer.php @@ -52,7 +52,7 @@ public function getDefinition(): FixerDefinitionInterface [ new CodeSample( 'getNextMeaningfulToken($functionToRemoveIndex); - if (!$tokens[$openingBraceIndex]->equals('(')) { - continue; - } - if ($tokens[$tokens->getNextMeaningfulToken($openingBraceIndex)]->isGivenKind(CT::T_FIRST_CLASS_CALLABLE)) { continue; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitNamespacedFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitNamespacedFixer.php index 4221fe92..d521007d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitNamespacedFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitNamespacedFixer.php @@ -45,7 +45,7 @@ final class PhpUnitNamespacedFixer extends AbstractFixer implements Configurable * space class and need a dedicated translation table. This trans- * lation table is defined in @see configure. * - * @var array|string[] Class Mappings + * @var array Class Mappings */ private $classMap; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitSizeClassFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitSizeClassFixer.php index 0696cdfd..3315ca19 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitSizeClassFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitSizeClassFixer.php @@ -72,11 +72,12 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en return; } - $this->ensureIsDockBlockWithAnnotation( + $this->ensureIsDocBlockWithAnnotation( $tokens, $classIndex, $this->configuration['group'], - self::SIZES + self::SIZES, + [], ); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitStrictFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitStrictFixer.php index 4d532566..5d3d565f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitStrictFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitStrictFixer.php @@ -34,7 +34,7 @@ final class PhpUnitStrictFixer extends AbstractPhpUnitFixer implements ConfigurableFixerInterface { /** - * @var array + * @var array */ private static array $assertionMap = [ 'assertAttributeEquals' => 'assertAttributeSame', diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestAnnotationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestAnnotationFixer.php index abee1f2e..455d512b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestAnnotationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestAnnotationFixer.php @@ -47,14 +47,14 @@ public function getDefinition(): FixerDefinitionInterface 'Adds or removes @test annotations from tests, following configuration.', [ new CodeSample('whitespacesConfig->getLineEnding()), new CodeSample('whitespacesConfig->getLineEnding(), ['style' => 'annotation']), ], @@ -225,7 +225,7 @@ private function createDocBlock(Tokens $tokens, int $docBlockIndex): void } /** - * @return Line[] + * @return list */ private function updateDocBlock(Tokens $tokens, int $docBlockIndex): array { @@ -236,9 +236,9 @@ private function updateDocBlock(Tokens $tokens, int $docBlockIndex): array } /** - * @param Line[] $lines + * @param list $lines * - * @return Line[] + * @return list */ private function updateLines(array $lines, Tokens $tokens, int $docBlockIndex): array { @@ -278,9 +278,9 @@ private function updateLines(array $lines, Tokens $tokens, int $docBlockIndex): /** * Take a one line doc block, and turn it into a multi line doc block. * - * @param Line[] $lines + * @param non-empty-list $lines * - * @return Line[] + * @return list */ private function splitUpDocBlock(array $lines, Tokens $tokens, int $docBlockIndex): array { @@ -298,7 +298,7 @@ private function splitUpDocBlock(array $lines, Tokens $tokens, int $docBlockInde /** * @todo check whether it's doable to use \PhpCsFixer\DocBlock\DocBlock::getSingleLineDocBlockEntry instead * - * @param Line[] $lines + * @param non-empty-list $lines */ private function getSingleLineDocBlockEntry(array $lines): string { @@ -377,9 +377,9 @@ private function findWhereDependsFunctionNameStarts(array $line): int } /** - * @param Line[] $lines + * @param list $lines * - * @return Line[] + * @return list */ private function addTestAnnotation(array $lines, Tokens $tokens, int $docBlockIndex): array { @@ -389,7 +389,8 @@ private function addTestAnnotation(array $lines, Tokens $tokens, int $docBlockIn $originalIndent = WhitespacesAnalyzer::detectIndent($tokens, $docBlockIndex); $lineEnd = $this->whitespacesConfig->getLineEnding(); - array_splice($lines, -1, 0, $originalIndent.' *'.$lineEnd.$originalIndent.' * @test'.$lineEnd); + array_splice($lines, -1, 0, [new Line($originalIndent.' *'.$lineEnd.$originalIndent.' * @test'.$lineEnd)]); + \assert(array_is_list($lines)); // we know it's list, but we need to tell PHPStan } return $lines; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestCaseStaticMethodCallsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestCaseStaticMethodCallsFixer.php index 692389c8..a081f66c 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestCaseStaticMethodCallsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestCaseStaticMethodCallsFixer.php @@ -51,13 +51,17 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i public const CALL_TYPE_STATIC = 'static'; /** - * @var array + * @var array */ - private array $staticMethods = [ + private const STATIC_METHODS = [ // Assert methods 'anything' => true, 'arrayHasKey' => true, 'assertArrayHasKey' => true, + 'assertArrayIsEqualToArrayIgnoringListOfKeys' => true, + 'assertArrayIsEqualToArrayOnlyConsideringListOfKeys' => true, + 'assertArrayIsIdenticalToArrayIgnoringListOfKeys' => true, + 'assertArrayIsIdenticalToArrayOnlyConsideringListOfKeys' => true, 'assertArrayNotHasKey' => true, 'assertArraySubset' => true, 'assertAttributeContains' => true, @@ -100,11 +104,11 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i 'assertDirectoryNotIsWritable' => true, 'assertDoesNotMatchRegularExpression' => true, 'assertEmpty' => true, - 'assertEqualXMLStructure' => true, 'assertEquals' => true, 'assertEqualsCanonicalizing' => true, 'assertEqualsIgnoringCase' => true, 'assertEqualsWithDelta' => true, + 'assertEqualXMLStructure' => true, 'assertFalse' => true, 'assertFileDoesNotExist' => true, 'assertFileEquals' => true, @@ -115,6 +119,8 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i 'assertFileIsNotWritable' => true, 'assertFileIsReadable' => true, 'assertFileIsWritable' => true, + 'assertFileMatchesFormat' => true, + 'assertFileMatchesFormatFile' => true, 'assertFileNotEquals' => true, 'assertFileNotEqualsCanonicalizing' => true, 'assertFileNotEqualsIgnoringCase' => true, @@ -134,6 +140,7 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i 'assertIsFloat' => true, 'assertIsInt' => true, 'assertIsIterable' => true, + 'assertIsList' => true, 'assertIsNotArray' => true, 'assertIsNotBool' => true, 'assertIsNotCallable' => true, @@ -196,11 +203,13 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i 'assertSameSize' => true, 'assertStringContainsString' => true, 'assertStringContainsStringIgnoringCase' => true, + 'assertStringContainsStringIgnoringLineEndings' => true, 'assertStringEndsNotWith' => true, 'assertStringEndsWith' => true, 'assertStringEqualsFile' => true, 'assertStringEqualsFileCanonicalizing' => true, 'assertStringEqualsFileIgnoringCase' => true, + 'assertStringEqualsStringIgnoringLineEndings' => true, 'assertStringMatchesFormat' => true, 'assertStringMatchesFormatFile' => true, 'assertStringNotContainsString' => true, @@ -250,6 +259,7 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i 'isInfinite' => true, 'isInstanceOf' => true, 'isJson' => true, + 'isList' => true, 'isNan' => true, 'isNull' => true, 'isReadable' => true, @@ -272,6 +282,7 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i 'resetCount' => true, 'stringContains' => true, 'stringEndsWith' => true, + 'stringEqualsStringIgnoringLineEndings' => true, 'stringStartsWith' => true, // TestCase methods @@ -295,16 +306,16 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i ]; /** - * @var array + * @var array */ - private array $allowedValues = [ + private const ALLOWED_VALUES = [ self::CALL_TYPE_THIS => true, self::CALL_TYPE_SELF => true, self::CALL_TYPE_STATIC => true, ]; /** - * @var array>> + * @var array> */ private array $conversionMap = [ self::CALL_TYPE_THIS => [[T_OBJECT_OPERATOR, '->'], [T_VARIABLE, '$this']], @@ -354,34 +365,32 @@ public function isRisky(): bool protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { - $thisFixer = $this; - return new FixerConfigurationResolver([ (new FixerOptionBuilder('call_type', 'The call type to use for referring to PHPUnit methods.')) ->setAllowedTypes(['string']) - ->setAllowedValues(array_keys($this->allowedValues)) + ->setAllowedValues(array_keys(self::ALLOWED_VALUES)) ->setDefault('static') ->getOption(), (new FixerOptionBuilder('methods', 'Dictionary of `method` => `call_type` values that differ from the default strategy.')) ->setAllowedTypes(['array']) - ->setAllowedValues([static function (array $option) use ($thisFixer): bool { + ->setAllowedValues([static function (array $option): bool { foreach ($option as $method => $value) { - if (!isset($thisFixer->staticMethods[$method])) { + if (!isset(self::STATIC_METHODS[$method])) { throw new InvalidOptionsException( sprintf( 'Unexpected "methods" key, expected any of %s, got "%s".', - Utils::naturalLanguageJoin(array_keys($thisFixer->staticMethods)), + Utils::naturalLanguageJoin(array_keys(self::STATIC_METHODS)), \gettype($method).'#'.$method ) ); } - if (!isset($thisFixer->allowedValues[$value])) { + if (!isset(self::ALLOWED_VALUES[$value])) { throw new InvalidOptionsException( sprintf( 'Unexpected value for method "%s", expected any of %s, got "%s".', $method, - Utils::naturalLanguageJoin(array_keys($thisFixer->allowedValues)), + Utils::naturalLanguageJoin(array_keys(self::ALLOWED_VALUES)), \is_object($value) ? \get_class($value) : (null === $value ? 'null' : \gettype($value).'#'.$value) ) ); @@ -429,7 +438,7 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en } } - if (!$tokens[$index]->isGivenKind(T_STRING) || !isset($this->staticMethods[$tokens[$index]->getContent()])) { + if (!$tokens[$index]->isGivenKind(T_STRING) || !isset(self::STATIC_METHODS[$tokens[$index]->getContent()])) { continue; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestClassRequiresCoversFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestClassRequiresCoversFixer.php index a8373290..b95abb75 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestClassRequiresCoversFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/PhpUnit/PhpUnitTestClassRequiresCoversFixer.php @@ -68,7 +68,7 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en return; // don't add `@covers` annotation for abstract base classes } - $this->ensureIsDockBlockWithAnnotation( + $this->ensureIsDocBlockWithAnnotation( $tokens, $classIndex, 'coversNothing', @@ -76,7 +76,11 @@ protected function applyPhpUnitClassFix(Tokens $tokens, int $startIndex, int $en 'covers', 'coversDefaultClass', 'coversNothing', - ] + ], + [ + 'phpunit\framework\attributes\coversclass', + 'phpunit\framework\attributes\coversnothing', + ], ); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/AlignMultilineCommentFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/AlignMultilineCommentFixer.php index 130b1349..eb6b3158 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/AlignMultilineCommentFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/AlignMultilineCommentFixer.php @@ -34,7 +34,7 @@ final class AlignMultilineCommentFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { /** - * @var null|int[] + * @var null|list */ private $tokenKinds; @@ -87,7 +87,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run before CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. + * Must run before CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocArrayTypeFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. * Must run after ArrayIndentationFixer. */ public function getPriority(): int diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/GeneralPhpdocTagRenameFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/GeneralPhpdocTagRenameFixer.php index 030aa338..7f68db60 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/GeneralPhpdocTagRenameFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/GeneralPhpdocTagRenameFixer.php @@ -92,7 +92,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->getOption(), (new FixerOptionBuilder('replacements', 'A map of tags to replace.')) ->setAllowedTypes(['array']) - ->setNormalizer(static function (Options $options, $value): array { + ->setNormalizer(static function (Options $options, array $value): array { $normalizedValue = []; foreach ($value as $from => $to) { @@ -118,7 +118,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn $from = trim($from); $to = trim($to); - if (!$options['case_sensitive']) { + if (false === $options['case_sensitive']) { $lowercaseFrom = strtolower($from); if (isset($normalizedValue[$lowercaseFrom]) && $normalizedValue[$lowercaseFrom] !== $to) { @@ -163,7 +163,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } if (true === $this->configuration['fix_annotation']) { - $regex = $this->configuration['fix_inline'] + $regex = true === $this->configuration['fix_inline'] ? '/"[^"]*"(*SKIP)(*FAIL)|\b(?<=@)(%s)\b/' : '/"[^"]*"(*SKIP)(*FAIL)|(?getContent())) { - $tokens->clearTokenAndMergeSurroundingWhitespace($index); + if (!Preg::match('#^/\*\*[\s\*]*\*/$#', $token->getContent())) { + continue; } + + if ( + $tokens[$index - 1]->isGivenKind([T_OPEN_TAG, T_WHITESPACE]) + && substr_count($tokens[$index - 1]->getContent(), "\n") > 0 + && $tokens[$index + 1]->isGivenKind(T_WHITESPACE) + && Preg::match('/^\R/', $tokens[$index + 1]->getContent()) + ) { + $tokens[$index - 1] = new Token([ + $tokens[$index - 1]->getId(), + Preg::replace('/\h*$/', '', $tokens[$index - 1]->getContent()), + ]); + + $newContent = Preg::replace('/^\R/', '', $tokens[$index + 1]->getContent()); + if ('' === $newContent) { + $tokens->clearAt($index + 1); + } else { + $tokens[$index + 1] = new Token([T_WHITESPACE, $newContent]); + } + } + + $tokens->clearTokenAndMergeSurroundingWhitespace($index); } } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/NoSuperfluousPhpdocTagsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/NoSuperfluousPhpdocTagsFixer.php index c8b62882..e98ffe61 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/NoSuperfluousPhpdocTagsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/NoSuperfluousPhpdocTagsFixer.php @@ -34,8 +34,21 @@ use PhpCsFixer\Tokenizer\Tokens; use PhpCsFixer\Tokenizer\TokensAnalyzer; +/** + * @phpstan-type _TypeInfo array{ + * types: list, + * allows_null: bool, + * } + * @phpstan-type _DocumentElement array{ + * index: int, + * type: 'classy'|'function'|'property', + * modifiers: array, + * types: array, + * } + */ final class NoSuperfluousPhpdocTagsFixer extends AbstractFixer implements ConfigurableFixerInterface { + /** @var _TypeInfo */ private const NO_TYPE_INFO = [ 'types' => [], 'allows_null' => true, @@ -46,7 +59,8 @@ public function getDefinition(): FixerDefinitionInterface return new FixerDefinition( 'Removes `@param`, `@return` and `@var` tags that don\'t provide any useful information.', [ - new CodeSample(' true]), - new CodeSample(' true], + ), + new CodeSample( + ' true]), - new CodeSample(' true], + ), + new CodeSample( + ' true], + ), + new CodeSample( + ' true]), +', + ['allow_unused_params' => true], + ), ] ); } @@ -196,6 +235,10 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setAllowedTypes(['bool']) ->setDefault(false) ->getOption(), + (new FixerOptionBuilder('allow_hidden_params', 'Whether `param` annotation for hidden params in method signature are allowed.')) + ->setAllowedTypes(['bool']) + ->setDefault(false) // @TODO set to `true` on 4.0 + ->getOption(), (new FixerOptionBuilder('allow_unused_params', 'Whether `param` annotation without actual signature is allowed (`true`) or considered superfluous (`false`).')) ->setAllowedTypes(['bool']) ->setDefault(false) @@ -204,12 +247,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn } /** - * @return null|array{ - * index: int, - * type: 'classy'|'function'|'property', - * modifiers: array, - * types: array, - * } + * @return null|_DocumentElement */ private function findDocumentedElement(Tokens $tokens, int $docCommentIndex): ?array { @@ -262,7 +300,7 @@ private function findDocumentedElement(Tokens $tokens, int $docCommentIndex): ?a return $element; } - if ($tokens[$index]->isGivenKind(T_FUNCTION)) { + if ($tokens[$index]->isGivenKind([T_FUNCTION, T_FN])) { $element['index'] = $index; $element['type'] = 'function'; @@ -291,14 +329,9 @@ private function findDocumentedElement(Tokens $tokens, int $docCommentIndex): ?a } /** - * @param array{ - * index: int, - * type: 'function', - * modifiers: array, - * types: array, - * } $element - * @param null|non-empty-string $namespace - * @param array $shortNames + * @param _DocumentElement&array{type: 'function'} $element + * @param null|non-empty-string $namespace + * @param array $shortNames */ private function fixFunctionDocComment( string $content, @@ -353,14 +386,9 @@ private function fixFunctionDocComment( } /** - * @param array{ - * index: int, - * type: 'property', - * modifiers: array, - * types: array, - * } $element - * @param null|non-empty-string $namespace - * @param array $shortNames + * @param _DocumentElement&array{type: 'property'} $element + * @param null|non-empty-string $namespace + * @param array $shortNames */ private function fixPropertyDocComment( string $content, @@ -388,12 +416,7 @@ private function fixPropertyDocComment( } /** - * @param array{ - * index: int, - * type: 'classy', - * modifiers: array, - * types: array, - * } $element + * @param _DocumentElement&array{type: 'classy'} $element */ private function fixClassDocComment(string $content, array $element): string { @@ -405,7 +428,7 @@ private function fixClassDocComment(string $content, array $element): string } /** - * @return array, allows_null: bool}> + * @return array */ private function getArgumentsInfo(Tokens $tokens, int $start, int $end): array { @@ -440,11 +463,22 @@ private function getArgumentsInfo(Tokens $tokens, int $start, int $end): array $argumentsInfo[$token->getContent()] = $info; } + // virtualise "hidden params" as if they would be regular ones + if (true === $this->configuration['allow_hidden_params']) { + $paramsString = $tokens->generatePartialCode($start, $end); + Preg::matchAll('|/\*[^$]*(\$\w+)[^*]*\*/|', $paramsString, $matches); + + /** @var non-empty-string $match */ + foreach ($matches[1] as $match) { + $argumentsInfo[$match] = self::NO_TYPE_INFO; // HINT: one could try to extract actual type for hidden param, for now we only indicate it's existence + } + } + return $argumentsInfo; } /** - * @return array{types: list, allows_null: bool} + * @return _TypeInfo */ private function getReturnTypeInfo(Tokens $tokens, int $closingParenthesisIndex): array { @@ -458,7 +492,7 @@ private function getReturnTypeInfo(Tokens $tokens, int $closingParenthesisIndex) /** * @param int $index The index of the first token of the type hint * - * @return array{types: list, allows_null: bool} + * @return _TypeInfo */ private function parseTypeHint(Tokens $tokens, int $index): array { @@ -509,6 +543,7 @@ private function parseTypeHint(Tokens $tokens, int $index): array } /** + * @param _TypeInfo $info * @param null|non-empty-string $namespace * @param array $symbolShortNames */ @@ -520,11 +555,11 @@ private function annotationIsSuperfluous( array $symbolShortNames ): bool { if ('param' === $annotation->getTag()->getName()) { - $regex = '{@param(?:\s+'.TypeExpression::REGEX_TYPES.')?(?!\S)(?:\s+(?:\&\s*)?(?:\.{3}\s*)?\$\S+)?(?:\s+(?(?!\*+\/)\S+))?}s'; + $regex = '{\*\h*@param(?:\h+'.TypeExpression::REGEX_TYPES.')?(?!\S)(?:\h+(?:\&\h*)?(?:\.{3}\h*)?\$\S+)?(?:\s+(?(?!\*+\/)\S+))?}s'; } elseif ('var' === $annotation->getTag()->getName()) { - $regex = '{@var(?:\s+'.TypeExpression::REGEX_TYPES.')?(?!\S)(?:\s+\$\S+)?(?:\s+(?(?!\*\/)\S+))?}s'; + $regex = '{\*\h*@var(?:\h+'.TypeExpression::REGEX_TYPES.')?(?!\S)(?:\h+\$\S+)?(?:\s+(?(?!\*\/)\S+))?}s'; } else { - $regex = '{@return(?:\s+'.TypeExpression::REGEX_TYPES.')?(?!\S)(?:\s+(?(?!\*\/)\S+))?}s'; + $regex = '{\*\h*@return(?:\h+'.TypeExpression::REGEX_TYPES.')?(?!\S)(?:\s+(?(?!\*\/)\S+))?}s'; } if (!Preg::match($regex, $annotation->getContent(), $matches)) { @@ -575,11 +610,11 @@ private function annotationIsSuperfluous( * Converts given types to lowercase, replaces imports aliases with * their matching FQCN, and finally sorts the result. * - * @param string[] $types The types to normalize + * @param list $types The types to normalize * @param null|non-empty-string $namespace * @param array $symbolShortNames The imports aliases * - * @return array The normalized types + * @return list The normalized types */ private function toComparableNames(array $types, ?string $namespace, ?string $currentSymbol, array $symbolShortNames): array { @@ -672,6 +707,9 @@ private function removeSuperfluousInheritDoc(string $docComment): string ~ix', '$1$2', $docComment); } + /** + * @param _DocumentElement $element + */ private function removeSuperfluousModifierAnnotation(DocBlock $docBlock, array $element): void { foreach (['abstract' => T_ABSTRACT, 'final' => T_FINAL] as $annotationType => $modifierToken) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php index 908a4bc0..0739be25 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php @@ -180,7 +180,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $newLines = []; foreach ($arguments as $argument) { - $type = $argument['type'] ?: 'mixed'; + $type = '' !== $argument['type'] ? $argument['type'] : 'mixed'; if (!str_starts_with($type, '?') && 'null' === strtolower($argument['default'])) { $type = 'null|'.$type; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAlignFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAlignFixer.php index fb18574e..bc6a9597 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAlignFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAlignFixer.php @@ -28,6 +28,7 @@ use PhpCsFixer\Preg; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; /** * @author Fabien Potencier @@ -35,6 +36,7 @@ * @author Sebastiaan Stok * @author Graham Campbell * @author Dariusz Rumiński + * @author Jakub Kwaśniewski */ final class PhpdocAlignFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { @@ -86,14 +88,22 @@ final class PhpdocAlignFixer extends AbstractFixer implements ConfigurableFixerI 'psalm-method', ]; + private const DEFAULT_SPACING = 1; + + private const DEFAULT_SPACING_KEY = '_default'; + private string $regex; private string $regexCommentLine; + private string $align; + /** - * @var string + * same spacing for all or specific for different tags. + * + * @var array|int */ - private $align; + private $spacing = 1; public function configure(array $configuration): void { @@ -128,6 +138,7 @@ public function configure(array $configuration): void $this->regex = '/'.$indentRegex.'\*\h*@(?J)(?:'.implode('|', $types).')'.$desc.'\h*\r?$/'; $this->regexCommentLine = '/'.$indentRegex.'\*(?!\h?+@)(?:\s+(?P\V+))(?align = $this->configuration['align']; + $this->spacing = $this->configuration['spacing']; } public function getDefinition(): FixerDefinitionInterface @@ -140,16 +151,24 @@ public function getDefinition(): FixerDefinitionInterface * @param int $code an HTTP response status code * @param bool $debug * @param mixed &$reference a parameter passed by reference + * + * @return Foo description foo + * + * @throws Foo description foo + * description foo + * */ EOF; return new FixerDefinition( - 'All items of the given phpdoc tags must be either left-aligned or (by default) aligned vertically.', + 'All items of the given PHPDoc tags must be either left-aligned or (by default) aligned vertically.', [ new CodeSample($code), new CodeSample($code, ['align' => self::ALIGN_VERTICAL]), new CodeSample($code, ['align' => self::ALIGN_LEFT]), + new CodeSample($code, ['align' => self::ALIGN_LEFT, 'spacing' => 2]), + new CodeSample($code, ['align' => self::ALIGN_LEFT, 'spacing' => ['param' => 2]]), ], ); } @@ -157,7 +176,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAnnotationWithoutDotFixer, PhpdocIndentFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocScalarFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToCommentFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. + * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAnnotationWithoutDotFixer, PhpdocArrayTypeFixer, PhpdocIndentFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocScalarFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToCommentFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. */ public function getPriority(): int { @@ -195,6 +214,17 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { + $allowPositiveIntegers = static function ($value) { + $spacings = \is_array($value) ? $value : [$value]; + foreach ($spacings as $val) { + if (\is_int($val) && $val <= 0) { + throw new InvalidOptionsException('The option "spacing" is invalid. All spacings must be greater than zero.'); + } + } + + return true; + }; + $tags = new FixerOptionBuilder( 'tags', 'The tags that should be aligned. Allowed values are tags with name (`\''.implode('\', \'', self::TAGS_WITH_NAME).'\'`), tags with method signature (`\''.implode('\', \'', self::TAGS_WITH_METHOD_SIGNATURE).'\'`) and any custom tag with description (e.g. `@tag `).' @@ -211,7 +241,16 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setDefault(self::ALIGN_VERTICAL) ; - return new FixerConfigurationResolver([$tags->getOption(), $align->getOption()]); + $spacing = new FixerOptionBuilder( + 'spacing', + 'Spacing between tag, hint, comment, signature, etc. You can set same spacing for all tags using a positive integer or different spacings for different tags using an associative array of positive integers `[\'tagA\' => spacingForA, \'tagB\' => spacingForB]`. If you want to define default spacing to more than 1 space use `_default` key in config array, e.g.: `[\'tagA\' => spacingForA, \'tagB\' => spacingForB, \'_default\' => spacingForAllOthers]`.' + ); + $spacing->setAllowedTypes(['int', 'int[]']) + ->setAllowedValues([$allowPositiveIntegers]) + ->setDefault(self::DEFAULT_SPACING) + ; + + return new FixerConfigurationResolver([$tags->getOption(), $align->getOption(), $spacing->getOption()]); } private function fixDocBlock(DocBlock $docBlock): void @@ -258,7 +297,10 @@ private function fixDocBlock(DocBlock $docBlock): void $varMax = max($varMax, \strlen($item['var'])); } + $itemOpeningLine = null; + $currTag = null; + $spacingForTag = $this->spacingForTag($currTag); // update foreach ($items as $j => $item) { @@ -270,10 +312,10 @@ private function fixDocBlock(DocBlock $docBlock): void continue; } - $extraIndent = 2; + $extraIndent = 2 * $spacingForTag; - if (\in_array($currTag, self::TAGS_WITH_NAME, true) || \in_array($currTag, self::TAGS_WITH_METHOD_SIGNATURE, true)) { - $extraIndent += $varMax + 1; + if (\in_array($itemOpeningLine['tag'], self::TAGS_WITH_NAME, true) || \in_array($itemOpeningLine['tag'], self::TAGS_WITH_METHOD_SIGNATURE, true)) { + $extraIndent += $varMax + $spacingForTag; } if ($hasStatic) { @@ -282,7 +324,8 @@ private function fixDocBlock(DocBlock $docBlock): void $line = $item['indent'] - .' * ' + .' * ' + .('' !== $itemOpeningLine['hint'] ? ' ' : '') .$this->getIndent( $tagMax + $hintMax + $extraIndent, $this->getLeftAlignedDescriptionIndent($items, $j) @@ -296,6 +339,10 @@ private function fixDocBlock(DocBlock $docBlock): void $currTag = $item['tag']; + $spacingForTag = $this->spacingForTag($currTag); + + $itemOpeningLine = $item; + $line = $item['indent'] .' * @' @@ -304,33 +351,33 @@ private function fixDocBlock(DocBlock $docBlock): void if ($hasStatic) { $line .= $this->getIndent( - $tagMax - \strlen($item['tag']) + 1, - '' !== $item['static'] ? 1 : 0 + $tagMax - \strlen($item['tag']) + $spacingForTag, + '' !== $item['static'] ? $spacingForTag : 0 ) - .($item['static'] ?: $this->getIndent(6 /* \strlen('static') */, 0)); - $hintVerticalAlignIndent = 1; + .('' !== $item['static'] ? $item['static'] : $this->getIndent(6 /* \strlen('static') */, 0)); + $hintVerticalAlignIndent = $spacingForTag; } else { - $hintVerticalAlignIndent = $tagMax - \strlen($item['tag']) + 1; + $hintVerticalAlignIndent = $tagMax - \strlen($item['tag']) + $spacingForTag; } $line .= $this->getIndent( $hintVerticalAlignIndent, - '' !== $item['hint'] ? 1 : 0 + '' !== $item['hint'] ? $spacingForTag : 0 ) .$item['hint']; if ('' !== $item['var']) { $line .= - $this->getIndent(($hintMax ?: -1) - \strlen($item['hint']) + 1) + $this->getIndent((0 !== $hintMax ? $hintMax : -1) - \strlen($item['hint']) + $spacingForTag, $spacingForTag) .$item['var'] .( '' !== $item['desc'] - ? $this->getIndent($varMax - \strlen($item['var']) + 1).$item['desc'] + ? $this->getIndent($varMax - \strlen($item['var']) + $spacingForTag, $spacingForTag).$item['desc'] : '' ); } elseif ('' !== $item['desc']) { - $line .= $this->getIndent($hintMax - \strlen($item['hint']) + 1).$item['desc']; + $line .= $this->getIndent($hintMax - \strlen($item['hint']) + $spacingForTag, $spacingForTag).$item['desc']; } $docBlock->getLine($current + $j)->setContent($line.$lineEnding); @@ -338,6 +385,13 @@ private function fixDocBlock(DocBlock $docBlock): void } } + private function spacingForTag(?string $tag): int + { + return (\is_int($this->spacing)) + ? $this->spacing + : ($this->spacing[$tag] ?? $this->spacing[self::DEFAULT_SPACING_KEY] ?? self::DEFAULT_SPACING); + } + /** * @TODO Introduce proper DTO instead of an array * @@ -418,18 +472,20 @@ private function getLeftAlignedDescriptionIndent(array $items, int $index): int return 0; } + $spacingForTag = $this->spacingForTag($item['tag']); + // Indent according to existing values: return - $this->getSentenceIndent($item['static']) + - $this->getSentenceIndent($item['tag']) + - $this->getSentenceIndent($item['hint']) + - $this->getSentenceIndent($item['var']); + $this->getSentenceIndent($item['static'], $spacingForTag) + + $this->getSentenceIndent($item['tag'], $spacingForTag) + + $this->getSentenceIndent($item['hint'], $spacingForTag) + + $this->getSentenceIndent($item['var'], $spacingForTag); } /** * Get indent for sentence. */ - private function getSentenceIndent(?string $sentence): int + private function getSentenceIndent(?string $sentence, int $spacingForTag = 1): int { if (null === $sentence) { return 0; @@ -437,6 +493,6 @@ private function getSentenceIndent(?string $sentence): int $length = \strlen($sentence); - return 0 === $length ? 0 : $length + 1; + return 0 === $length ? 0 : $length + $spacingForTag; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php index 8cacdc38..fd48122e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocAnnotationWithoutDotFixer.php @@ -29,7 +29,7 @@ final class PhpdocAnnotationWithoutDotFixer extends AbstractFixer { /** - * @var string[] + * @var list */ private array $tags = ['throws', 'return', 'param', 'internal', 'deprecated', 'var', 'type']; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php new file mode 100644 index 00000000..f3f64c11 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocArrayTypeFixer.php @@ -0,0 +1,92 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\Phpdoc; + +use PhpCsFixer\AbstractPhpdocTypesFixer; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Tokens; + +final class PhpdocArrayTypeFixer extends AbstractPhpdocTypesFixer +{ + public function isCandidate(Tokens $tokens): bool + { + return $tokens->isTokenKindFound(T_DOC_COMMENT); + } + + public function isRisky(): bool + { + return true; + } + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'PHPDoc `array` type must be used instead of `T[]`.', + [ + new CodeSample(<<<'PHP' + ', $level); + }, + $type, + ); + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocIndentFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocIndentFixer.php index dcb49fc2..9690977a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocIndentFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocIndentFixer.php @@ -48,7 +48,7 @@ class DocBlocks /** * {@inheritdoc} * - * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. + * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocArrayTypeFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. * Must run after IndentationTypeFixer, PhpdocToCommentFixer. */ public function getPriority(): int diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocListTypeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocListTypeFixer.php new file mode 100644 index 00000000..9d2cdff9 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocListTypeFixer.php @@ -0,0 +1,70 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\Phpdoc; + +use PhpCsFixer\AbstractPhpdocTypesFixer; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Tokens; + +final class PhpdocListTypeFixer extends AbstractPhpdocTypesFixer +{ + public function isCandidate(Tokens $tokens): bool + { + return $tokens->isTokenKindFound(T_DOC_COMMENT); + } + + public function isRisky(): bool + { + return true; + } + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'PHPDoc `list` type must be used instead of `array` without a key.', + [ + new CodeSample(<<<'PHP' + $x + * @param array> $y + */ + + PHP), + ], + null, + 'Risky when `array` key should be present, but is missing.' + ); + } + + /** + * {@inheritdoc} + * + * Must run before PhpdocAlignFixer, PhpdocTypesOrderFixer. + * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, PhpdocArrayTypeFixer, PhpdocIndentFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. + */ + public function getPriority(): int + { + return 1; + } + + protected function normalize(string $type): string + { + return Preg::replace('/array(?=<(?:[^,<]|<[^>]+>)+(>|{|\())/i', 'list', $type); + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoUselessInheritdocFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoUselessInheritdocFixer.php index 4174f2d9..b1e88a3a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoUselessInheritdocFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocNoUselessInheritdocFixer.php @@ -121,7 +121,7 @@ private function fixToken(Tokens $tokens, int $tokenIndex): void $count ); - if ($count) { + if ($count > 0) { $tokens[$tokenIndex] = new Token([T_DOC_COMMENT, $content]); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderByValueFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderByValueFixer.php index c3728efc..7b8568c5 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderByValueFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderByValueFixer.php @@ -38,7 +38,7 @@ final class PhpdocOrderByValueFixer extends AbstractFixer implements Configurabl public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( - 'Order phpdoc tags by value.', + 'Order PHPDoc tags by value.', [ new CodeSample( '.+\s+)?\$(?P[^\s]+).*/', + '/(?s)\*\s*@%s\s+(?P.+\s+)?\$(?P\S+).*/', $type ); @@ -194,7 +194,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setAllowedValues([ new AllowedValueSubset($allowedValues), ]) - ->setNormalizer(static function (Options $options, $value): array { + ->setNormalizer(static function (Options $options, array $value): array { $normalized = []; foreach ($value as $annotation) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderFixer.php index 4ae2c5f1..d858f535 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocOrderFixer.php @@ -88,7 +88,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn return new FixerConfigurationResolver([ (new FixerOptionBuilder('order', 'Sequence in which annotations in PHPDoc should be ordered.')) ->setAllowedTypes(['string[]']) - ->setAllowedValues([static function ($order) { + ->setAllowedValues([static function (array $order): bool { if (\count($order) < 2) { throw new InvalidOptionsException('The option "order" value is invalid. Minimum two tags are required.'); } @@ -102,6 +102,9 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { + /** @var list */ + $order = $this->configuration['order']; + foreach ($tokens as $index => $token) { if (!$token->isGivenKind(T_DOC_COMMENT)) { continue; @@ -111,7 +114,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $content = $token->getContent(); // sort annotations - $successors = $this->configuration['order']; + $successors = $order; while (\count($successors) >= 3) { $predecessor = array_shift($successors); $content = $this->moveAnnotationsBefore($predecessor, $successors, $content); @@ -119,7 +122,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // we're parsing the content last time to make sure the internal // state of the docblock is correct after the modifications - $predecessors = $this->configuration['order']; + $predecessors = $order; $last = array_pop($predecessors); $content = $this->moveAnnotationsAfter($last, $predecessors, $content); @@ -131,8 +134,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void /** * Move all given annotations in before given set of annotations. * - * @param string $move Tag of annotations that should be moved - * @param string[] $before Tags of annotations that should moved annotations be placed before + * @param string $move Tag of annotations that should be moved + * @param list $before Tags of annotations that should moved annotations be placed before */ private function moveAnnotationsBefore(string $move, array $before, string $content): string { @@ -170,8 +173,8 @@ private function moveAnnotationsBefore(string $move, array $before, string $cont /** * Move all given annotations after given set of annotations. * - * @param string $move Tag of annotations that should be moved - * @param string[] $after Tags of annotations that should moved annotations be placed after + * @param string $move Tag of annotations that should be moved + * @param list $after Tags of annotations that should moved annotations be placed after */ private function moveAnnotationsAfter(string $move, array $after, string $content): string { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocParamOrderFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocParamOrderFixer.php index fb3f4124..dbed46eb 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocParamOrderFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocParamOrderFixer.php @@ -103,7 +103,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return Token[] + * @return list */ private function getFunctionParamNames(Tokens $tokens, int $paramBlockStart): array { @@ -124,8 +124,8 @@ private function getFunctionParamNames(Tokens $tokens, int $paramBlockStart): ar /** * Overwrite the param annotations in order. * - * @param Token[] $paramNames - * @param Annotation[] $paramAnnotations + * @param list $paramNames + * @param list $paramAnnotations */ private function rewriteDocBlock(DocBlock $doc, array $paramNames, array $paramAnnotations): DocBlock { @@ -161,10 +161,10 @@ private function rewriteDocBlock(DocBlock $doc, array $paramNames, array $paramA /** * Sort the param annotations according to the function parameters. * - * @param Token[] $funcParamNames - * @param Annotation[] $paramAnnotations + * @param list $funcParamNames + * @param list $paramAnnotations * - * @return string[] + * @return list */ private function sortParamAnnotations(array $funcParamNames, array $paramAnnotations): array { @@ -181,9 +181,10 @@ private function sortParamAnnotations(array $funcParamNames, array $paramAnnotat } // Detect superfluous annotations - /** @var Annotation[] $invalidParams */ - $invalidParams = array_diff_key($paramAnnotations, $validParams); - $invalidParams = array_values($invalidParams); + /** @var list $invalidParams */ + $invalidParams = array_values( + array_diff_key($paramAnnotations, $validParams) + ); // Append invalid parameters to the (ordered) valid ones $orderedParams = array_values($validParams); @@ -197,9 +198,9 @@ private function sortParamAnnotations(array $funcParamNames, array $paramAnnotat /** * Fetch all annotations except the param ones. * - * @param Annotation[] $paramAnnotations + * @param list $paramAnnotations * - * @return string[] + * @return list */ private function getOtherAnnotationsBetweenParams(DocBlock $doc, array $paramAnnotations): array { @@ -227,9 +228,9 @@ private function getOtherAnnotationsBetweenParams(DocBlock $doc, array $paramAnn /** * Return the indices of the lines of a specific parameter annotation. * - * @param Annotation[] $paramAnnotations + * @param list $paramAnnotations * - * @return null|array + * @return ?list */ private function findParamAnnotationByIdentifier(array $paramAnnotations, string $identifier): ?array { @@ -237,7 +238,7 @@ private function findParamAnnotationByIdentifier(array $paramAnnotations, string $blockMatch = false; $blockIndices = []; - $paramRegex = '/\*\s*@param\s*(?:|'.TypeExpression::REGEX_TYPES.'\s*)&?(?=\$\b)'.preg_quote($identifier).'\b/'; + $paramRegex = '/\*\h*@param\h*(?:|'.TypeExpression::REGEX_TYPES.'\h*)&?(?=\$\b)'.preg_quote($identifier).'\b/'; foreach ($paramAnnotations as $i => $param) { $blockStart = Preg::match('/\s*{\s*/', $param->getContent()); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocReturnSelfReferenceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocReturnSelfReferenceFixer.php index f672e1ee..0f243019 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocReturnSelfReferenceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocReturnSelfReferenceFixer.php @@ -33,7 +33,7 @@ final class PhpdocReturnSelfReferenceFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var string[] + * @var list */ private static array $toTypes = [ '$this', diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocScalarFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocScalarFixer.php index df397ef0..70a6b323 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocScalarFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocScalarFixer.php @@ -82,7 +82,7 @@ function sample($a, $b, $c) /** * {@inheritdoc} * - * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. + * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocArrayTypeFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. * Must run after PhpdocTypesFixer. */ public function getPriority(): int @@ -113,10 +113,16 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn protected function normalize(string $type): string { + $suffix = ''; + while (str_ends_with($type, '[]')) { + $type = substr($type, 0, -2); + $suffix .= '[]'; + } + if (\in_array($type, $this->configuration['types'], true)) { - return self::$types[$type]; + $type = self::$types[$type]; } - return $type; + return $type.$suffix; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocSeparationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocSeparationFixer.php index 03275367..197bab67 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocSeparationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocSeparationFixer.php @@ -38,7 +38,7 @@ final class PhpdocSeparationFixer extends AbstractFixer implements ConfigurableF /** * @internal * - * @var string[][] + * @var list> */ public const OPTION_GROUPS_DEFAULT = [ ['author', 'copyright', 'license'], @@ -48,7 +48,7 @@ final class PhpdocSeparationFixer extends AbstractFixer implements ConfigurableF ]; /** - * @var string[][] + * @var list> */ private array $groups; @@ -117,7 +117,7 @@ public function configure(array $configuration): void * {@inheritdoc} * * Must run before PhpdocAlignFixer. - * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, PhpUnitInternalClassFixer, PhpUnitSizeClassFixer, PhpUnitTestClassRequiresCoversFixer, PhpdocIndentFixer, PhpdocNoAccessFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocOrderFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. + * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, PhpUnitAttributesFixer, PhpUnitInternalClassFixer, PhpUnitSizeClassFixer, PhpUnitTestClassRequiresCoversFixer, PhpdocIndentFixer, PhpdocNoAccessFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocOrderFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. */ public function getPriority(): int { @@ -146,7 +146,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { - $allowTagToBelongToOnlyOneGroup = static function ($groups) { + $allowTagToBelongToOnlyOneGroup = static function (array $groups): bool { $tags = []; foreach ($groups as $groupIndex => $group) { foreach ($group as $member) { @@ -221,7 +221,7 @@ private function fixAnnotations(DocBlock $doc): void if (true === $shouldBeTogether) { $this->ensureAreTogether($doc, $annotation, $next); - } elseif (false === $shouldBeTogether || !$this->configuration['skip_unlisted_annotations']) { + } elseif (false === $shouldBeTogether || false === $this->configuration['skip_unlisted_annotations']) { $this->ensureAreSeparate($doc, $annotation, $next); } } @@ -295,7 +295,7 @@ private function shouldBeTogether(Annotation $first, Annotation $second, array $ private function tagName(Annotation $annotation): ?string { - Preg::match('/@([a-zA-Z0-9_\\\\-]+(?=\s|$|\())/', $annotation->getContent(), $matches); + Preg::match('/@([a-zA-Z0-9_\\\-]+(?=\s|$|\())/', $annotation->getContent(), $matches); return $matches[1] ?? null; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTagTypeFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTagTypeFixer.php index 947b526c..5aac1717 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTagTypeFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTagTypeFixer.php @@ -168,7 +168,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn 'var' => 'annotation', 'version' => 'annotation', ]) - ->setNormalizer(static function (Options $options, $value): array { + ->setNormalizer(static function (Options $options, array $value): array { $normalized = []; foreach ($value as $tag => $type) { @@ -182,7 +182,7 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn } /** - * @param list $parts + * @param array $parts */ private function tagIsSurroundedByText(array $parts, int $index): bool { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocToCommentFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocToCommentFixer.php index 402ca5fc..d6372d8f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocToCommentFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocToCommentFixer.php @@ -34,9 +34,10 @@ final class PhpdocToCommentFixer extends AbstractFixer implements ConfigurableFixerInterface { /** - * @var string[] + * @var list */ private array $ignoredTags = []; + private bool $allowBeforeReturnStatement = false; public function isCandidate(Tokens $tokens): bool { @@ -46,7 +47,7 @@ public function isCandidate(Tokens $tokens): bool /** * {@inheritdoc} * - * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyCommentFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocIndentFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer, SingleLineCommentSpacingFixer, SingleLineCommentStyleFixer. + * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyCommentFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocArrayTypeFixer, PhpdocIndentFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer, SingleLineCommentSpacingFixer, SingleLineCommentStyleFixer. * Must run after CommentToPhpdocFixer. */ public function getPriority(): int @@ -90,11 +91,27 @@ public function getDefinition(): FixerDefinitionInterface ', ['ignored_tags' => ['todo']] ), + new CodeSample( + ' $sqlite) { + $sqlite->open($path); +} + +function returnClassName() { + /** @var class-string */ + return \StdClass::class; +} +', + ['allow_before_return_statement' => true] + ), ] ); } - public function configure(array $configuration = null): void + public function configure(array $configuration): void { parent::configure($configuration); @@ -102,6 +119,8 @@ public function configure(array $configuration = null): void static fn (string $tag): string => strtolower($tag), $this->configuration['ignored_tags'] ); + + $this->allowBeforeReturnStatement = true === $this->configuration['allow_before_return_statement']; } protected function createConfigurationDefinition(): FixerConfigurationResolverInterface @@ -111,6 +130,10 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ->setAllowedTypes(['array']) ->setDefault([]) ->getOption(), + (new FixerOptionBuilder('allow_before_return_statement', 'Whether to allow PHPDoc before return statement.')) + ->setAllowedTypes(['bool']) + ->setDefault(false) // @TODO 4.0: set to `true` + ->getOption(), ]); } @@ -127,11 +150,15 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } + if ($this->allowBeforeReturnStatement && $commentsAnalyzer->isBeforeReturn($tokens, $index)) { + continue; + } + if ($commentsAnalyzer->isBeforeStructuralElement($tokens, $index)) { continue; } - if (0 < Preg::matchAll('~\@([a-zA-Z0-9_\\\\-]+)\b~', $token->getContent(), $matches)) { + if (0 < Preg::matchAll('~\@([a-zA-Z0-9_\\\-]+)\b~', $token->getContent(), $matches)) { foreach ($matches[1] as $match) { if (\in_array(strtolower($match), $this->ignoredTags, true)) { continue 2; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimConsecutiveBlankLineSeparationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimConsecutiveBlankLineSeparationFixer.php index 33a4a037..6b107af1 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimConsecutiveBlankLineSeparationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimConsecutiveBlankLineSeparationFixer.php @@ -63,7 +63,7 @@ function fnc($foo) {} * {@inheritdoc} * * Must run before PhpdocAlignFixer. - * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, PhpdocIndentFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. + * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, PhpUnitAttributesFixer, PhpdocIndentFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. */ public function getPriority(): int { @@ -165,13 +165,16 @@ private function findNonBlankLine(DocBlock $doc, int $after): ?int private function findFirstAnnotationOrEnd(DocBlock $doc): int { - $index = null; foreach ($doc->getLines() as $index => $line) { if ($line->containsATag()) { return $index; } } + if (!isset($index)) { + throw new \LogicException('PHPDoc has empty lines collection.'); + } + return $index; // no Annotation, return the last line } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimFixer.php index c472d0d9..d6b2391e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTrimFixer.php @@ -47,7 +47,7 @@ final class Foo {} * {@inheritdoc} * * Must run before PhpdocAlignFixer. - * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, PhpUnitTestAnnotationFixer, PhpdocIndentFixer, PhpdocNoAccessFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocOrderFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. + * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, PhpUnitAttributesFixer, PhpUnitTestAnnotationFixer, PhpdocIndentFixer, PhpdocNoAccessFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocOrderFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. */ public function getPriority(): int { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesFixer.php index 761f0b55..e5b02477 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesFixer.php @@ -15,7 +15,6 @@ namespace PhpCsFixer\Fixer\Phpdoc; use PhpCsFixer\AbstractPhpdocTypesFixer; -use PhpCsFixer\DocBlock\TypeExpression; use PhpCsFixer\Fixer\ConfigurableFixerInterface; use PhpCsFixer\FixerConfiguration\AllowedValueSubset; use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; @@ -35,7 +34,7 @@ final class PhpdocTypesFixer extends AbstractPhpdocTypesFixer implements Configu /** * Available types, grouped. * - * @var array + * @var array> */ private const POSSIBLE_TYPES = [ 'simple' => [ @@ -111,7 +110,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocScalarFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. + * Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocArrayTypeFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocListTypeFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocParamOrderFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocReturnSelfReferenceFixer, PhpdocScalarFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer. * Must run after PhpdocIndentFixer. */ public function getPriority(): int @@ -129,32 +128,18 @@ public function getPriority(): int protected function normalize(string $type): string { - $typeExpression = new TypeExpression($type, null, []); - - $typeExpression->walkTypes(function (TypeExpression $type): void { - if (!$type->isUnionType()) { - $value = $type->toString(); - $valueLower = strtolower($value); - if (isset($this->typesSetToFix[$valueLower])) { - $value = $valueLower; - } - - // normalize shape/callable/generic identifiers too - // TODO parse them as inner types and this will be not needed then - $value = Preg::replaceCallback( - '/^(\??\s*)([^()[\]{}<>\'"]+)(?])/', - fn ($matches) => $matches[1].$this->normalize($matches[2]).$matches[3], - $value - ); - - // TODO TypeExpression should be immutable and walkTypes method should be changed to mapTypes method - \Closure::bind(static function () use ($type, $value): void { - $type->value = $value; - }, null, TypeExpression::class)(); - } - }); - - return $typeExpression->toString(); + $typeLower = strtolower($type); + if (isset($this->typesSetToFix[$typeLower])) { + $type = $typeLower; + } + + // normalize shape/callable/generic identifiers too + // TODO parse them as inner types and this will be not needed then + return Preg::replaceCallback( + '/^(\??\s*)([^()[\]{}<>\'"]+)(?])/', + fn ($matches) => $matches[1].$this->normalize($matches[2]).$matches[3], + $type + ); } protected function createConfigurationDefinition(): FixerConfigurationResolverInterface diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesOrderFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesOrderFixer.php index 044eb8f6..0bf50195 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesOrderFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocTypesOrderFixer.php @@ -97,7 +97,7 @@ public function getDefinition(): FixerDefinitionInterface * {@inheritdoc} * * Must run before PhpdocAlignFixer. - * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, PhpdocIndentFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. + * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, PhpdocArrayTypeFixer, PhpdocIndentFixer, PhpdocListTypeFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer. */ public function getPriority(): int { @@ -153,7 +153,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void // fix @method parameters types $line = $doc->getLine($annotation->getStart()); - $line->setContent(Preg::replaceCallback('/@method\s+'.TypeExpression::REGEX_TYPES.'\s+\K(?&callable)/', function (array $matches) { + $line->setContent(Preg::replaceCallback('/\*\h*@method\h+'.TypeExpression::REGEX_TYPES.'\h+\K(?&callable)/', function (array $matches) { $typeExpression = new TypeExpression($matches[0], null, []); return implode('|', $this->sortTypes($typeExpression)); @@ -165,11 +165,11 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @return string[] + * @return list */ private function sortTypes(TypeExpression $typeExpression): array { - $normalizeType = static fn (string $type): string => Preg::replace('/^\\??\\\?/', '', $type); + $normalizeType = static fn (string $type): string => Preg::replace('/^\(*\??\\\?/', '', $type); $typeExpression->sortTypes( function (TypeExpression $a, TypeExpression $b) use ($normalizeType): int { @@ -188,7 +188,7 @@ function (TypeExpression $a, TypeExpression $b) use ($normalizeType): int { } if ('alpha' === $this->configuration['sort_algorithm']) { - return $this->configuration['case_sensitive'] ? strcmp($a, $b) : strcasecmp($a, $b); + return true === $this->configuration['case_sensitive'] ? $a <=> $b : strcasecmp($a, $b); } return 0; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocVarWithoutNameFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocVarWithoutNameFixer.php index f42b2d9f..712b0728 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocVarWithoutNameFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Phpdoc/PhpdocVarWithoutNameFixer.php @@ -124,7 +124,7 @@ private function fixLine(Line $line): void } /** - * @return Line[] + * @return array */ private function getFirstLevelLines(DocBlock $docBlock): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ReturnNotation/SimplifiedNullReturnFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ReturnNotation/SimplifiedNullReturnFixer.php index bc222aa3..b745b212 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/ReturnNotation/SimplifiedNullReturnFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/ReturnNotation/SimplifiedNullReturnFixer.php @@ -125,7 +125,8 @@ private function isStrictOrNullableReturnTypeFunction(Tokens $tokens, int $retur } while ($closingCurlyBraceIndex < $returnIndex); $possibleVoidIndex = $tokens->getPrevMeaningfulToken($openingCurlyBraceIndex); - $isStrictReturnType = $tokens[$possibleVoidIndex]->isGivenKind(T_STRING) && 'void' !== $tokens[$possibleVoidIndex]->getContent(); + $isStrictReturnType = $tokens[$possibleVoidIndex]->isGivenKind([T_STRING, CT::T_ARRAY_TYPEHINT]) + && 'void' !== $tokens[$possibleVoidIndex]->getContent(); $nullableTypeIndex = $tokens->getNextTokenOfKind($functionIndex, [[CT::T_NULLABLE_TYPE]]); $isNullableReturnType = null !== $nullableTypeIndex && $nullableTypeIndex < $openingCurlyBraceIndex; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/DeclareStrictTypesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/DeclareStrictTypesFixer.php index 4a83a9de..7e8172c2 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/DeclareStrictTypesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/DeclareStrictTypesFixer.php @@ -53,7 +53,7 @@ public function getPriority(): int public function isCandidate(Tokens $tokens): bool { - return isset($tokens[0]) && $tokens[0]->isGivenKind(T_OPEN_TAG); + return $tokens->isMonolithicPhp() && !$tokens->isTokenKindFound(T_OPEN_TAG_WITH_ECHO); } public function isRisky(): bool @@ -63,17 +63,11 @@ public function isRisky(): bool protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { - // check if the declaration is already done - $searchIndex = $tokens->getNextMeaningfulToken(0); - if (null === $searchIndex) { - $this->insertSequence($tokens); // declaration not found, insert one + $openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0; - return; - } - - $sequenceLocation = $tokens->findSequence([[T_DECLARE, 'declare'], '(', [T_STRING, 'strict_types'], '=', [T_LNUMBER], ')'], $searchIndex, null, false); + $sequenceLocation = $tokens->findSequence([[T_DECLARE, 'declare'], '(', [T_STRING, 'strict_types'], '=', [T_LNUMBER], ')'], $openTagIndex, null, false); if (null === $sequenceLocation) { - $this->insertSequence($tokens); // declaration not found, insert one + $this->insertSequence($openTagIndex, $tokens); // declaration not found, insert one return; } @@ -102,7 +96,7 @@ private function fixStrictTypesCasingAndValue(Tokens $tokens, array $sequence): } } - private function insertSequence(Tokens $tokens): void + private function insertSequence(int $openTagIndex, Tokens $tokens): void { $sequence = [ new Token([T_DECLARE, 'declare']), @@ -113,28 +107,26 @@ private function insertSequence(Tokens $tokens): void new Token(')'), new Token(';'), ]; - $endIndex = \count($sequence); + $nextIndex = $openTagIndex + \count($sequence) + 1; - $tokens->insertAt(1, $sequence); + $tokens->insertAt($openTagIndex + 1, $sequence); - // start index of the sequence is always 1 here, 0 is always open tag - // transform "getContent(), "\n")) { - $tokens[0] = new Token([$tokens[0]->getId(), trim($tokens[0]->getContent()).' ']); + // transform "getContent(); + if (!str_contains($content, ' ') || str_contains($content, "\n")) { + $tokens[$openTagIndex] = new Token([$tokens[$openTagIndex]->getId(), trim($tokens[$openTagIndex]->getContent()).' ']); } - if ($endIndex === \count($tokens) - 1) { + if (\count($tokens) === $nextIndex) { return; // no more tokens after sequence, single_blank_line_at_eof might add a line } $lineEnding = $this->whitespacesConfig->getLineEnding(); - if (!$tokens[1 + $endIndex]->isWhitespace()) { - $tokens->insertAt(1 + $endIndex, new Token([T_WHITESPACE, $lineEnding])); - - return; + if ($tokens[$nextIndex]->isWhitespace()) { + $content = $tokens[$nextIndex]->getContent(); + $tokens[$nextIndex] = new Token([T_WHITESPACE, $lineEnding.ltrim($content, " \t")]); + } else { + $tokens->insertAt($nextIndex, new Token([T_WHITESPACE, $lineEnding])); } - - $content = $tokens[1 + $endIndex]->getContent(); - $tokens[1 + $endIndex] = new Token([T_WHITESPACE, $lineEnding.ltrim($content, " \t")]); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/StrictParamFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/StrictParamFixer.php index d9280969..e0f12f33 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/StrictParamFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Strict/StrictParamFixer.php @@ -91,6 +91,9 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } } + /** + * @param list $functionParams + */ private function fixFunction(Tokens $tokens, int $functionIndex, array $functionParams): void { $startBraceIndex = $tokens->getNextTokenOfKind($functionIndex, ['(']); @@ -135,7 +138,7 @@ private function fixFunction(Tokens $tokens, int $functionIndex, array $function for ($i = $paramsQuantity; $i < $functionParamsQuantity; ++$i) { // function call do not have all params that are required to set useStrict flag, exit from method! - if (!$functionParams[$i]) { + if (null === $functionParams[$i]) { return; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/EscapeImplicitBackslashesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/EscapeImplicitBackslashesFixer.php index af0a103d..786134ff 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/EscapeImplicitBackslashesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/EscapeImplicitBackslashesFixer.php @@ -14,23 +14,29 @@ namespace PhpCsFixer\Fixer\StringNotation; -use PhpCsFixer\AbstractFixer; +use PhpCsFixer\AbstractProxyFixer; use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\Fixer\DeprecatedFixerInterface; use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; -use PhpCsFixer\Preg; -use PhpCsFixer\Tokenizer\Token; -use PhpCsFixer\Tokenizer\Tokens; /** * @author Filippo Tessarotto + * @author Michael Vorisek + * + * @deprecated Use `string_implicit_backslashes` with config: ['single_quoted' => 'ignore', 'double_quoted' => 'escape', 'heredoc' => 'escape'] (default) */ -final class EscapeImplicitBackslashesFixer extends AbstractFixer implements ConfigurableFixerInterface +final class EscapeImplicitBackslashesFixer extends AbstractProxyFixer implements ConfigurableFixerInterface, DeprecatedFixerInterface { + public function getSuccessorsNames(): array + { + return array_keys($this->proxyFixers); + } + public function getDefinition(): FixerDefinitionInterface { $codeSample = <<<'EOF' @@ -73,69 +79,43 @@ public function getDefinition(): FixerDefinitionInterface ); } - public function isCandidate(Tokens $tokens): bool - { - return $tokens->isAnyTokenKindsFound([T_ENCAPSED_AND_WHITESPACE, T_CONSTANT_ENCAPSED_STRING]); - } - /** * {@inheritdoc} * * Must run before HeredocToNowdocFixer, SingleQuoteFixer. - * Must run after BacktickToShellExecFixer. + * Must run after BacktickToShellExecFixer, MultilineStringToHeredocFixer. */ public function getPriority(): int { - return 15; + return parent::getPriority(); } - protected function applyFix(\SplFileInfo $file, Tokens $tokens): void + public function configure(array $configuration): void { - static $singleQuotedRegex = '/(? $token) { - $content = $token->getContent(); - if ($token->equalsAny(['"', 'b"', 'B"'])) { - $doubleQuoteOpened = !$doubleQuoteOpened; - } - if (!$token->isGivenKind([T_ENCAPSED_AND_WHITESPACE, T_CONSTANT_ENCAPSED_STRING]) || !str_contains($content, '\\')) { - continue; - } - - // Nowdoc syntax - if ($token->isGivenKind(T_ENCAPSED_AND_WHITESPACE) && '\'' === substr(rtrim($tokens[$index - 1]->getContent()), -1)) { - continue; - } - - $firstTwoCharacters = strtolower(substr($content, 0, 2)); - $isSingleQuotedString = $token->isGivenKind(T_CONSTANT_ENCAPSED_STRING) && ('\'' === $content[0] || 'b\'' === $firstTwoCharacters); - $isDoubleQuotedString = - ($token->isGivenKind(T_CONSTANT_ENCAPSED_STRING) && ('"' === $content[0] || 'b"' === $firstTwoCharacters)) - || ($token->isGivenKind(T_ENCAPSED_AND_WHITESPACE) && $doubleQuoteOpened); - $isHeredocSyntax = !$isSingleQuotedString && !$isDoubleQuotedString; - if ( - (false === $this->configuration['single_quoted'] && $isSingleQuotedString) - || (false === $this->configuration['double_quoted'] && $isDoubleQuotedString) - || (false === $this->configuration['heredoc_syntax'] && $isHeredocSyntax) - ) { - continue; - } - - $regex = $heredocSyntaxRegex; - if ($isSingleQuotedString) { - $regex = $singleQuotedRegex; - } elseif ($isDoubleQuotedString) { - $regex = $doubleQuotedRegex; - } - - $newContent = Preg::replace($regex, '\\\\\\\\$1', $content); - if ($newContent !== $content) { - $tokens[$index] = new Token([$token->getId(), $newContent]); - } - } + parent::configure($configuration); + + /** @var StringImplicitBackslashesFixer */ + $stringImplicitBackslashesFixer = $this->proxyFixers['string_implicit_backslashes']; + + $stringImplicitBackslashesFixer->configure([ + 'single_quoted' => true === $this->configuration['single_quoted'] ? 'escape' : 'ignore', + 'double_quoted' => true === $this->configuration['double_quoted'] ? 'escape' : 'ignore', + 'heredoc' => true === $this->configuration['heredoc_syntax'] ? 'escape' : 'ignore', + ]); + } + + protected function createProxyFixers(): array + { + $stringImplicitBackslashesFixer = new StringImplicitBackslashesFixer(); + $stringImplicitBackslashesFixer->configure([ + 'single_quoted' => 'ignore', + 'double_quoted' => 'escape', + 'heredoc' => 'escape', + ]); + + return [ + $stringImplicitBackslashesFixer, + ]; } protected function createConfigurationDefinition(): FixerConfigurationResolverInterface diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/ExplicitStringVariableFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/ExplicitStringVariableFixer.php index 92bc84ff..5194a72e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/ExplicitStringVariableFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/ExplicitStringVariableFixer.php @@ -52,11 +52,12 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * + * Must run before NoUselessConcatOperatorFixer. * Must run after BacktickToShellExecFixer. */ public function getPriority(): int { - return 0; + return 6; } public function isCandidate(Tokens $tokens): bool @@ -123,7 +124,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void foreach ($variableTokens as $distinctVariableSet) { if (1 === \count($distinctVariableSet['tokens'])) { - $singleVariableIndex = key($distinctVariableSet['tokens']); + $singleVariableIndex = array_key_first($distinctVariableSet['tokens']); $singleVariableToken = current($distinctVariableSet['tokens']); $tokens->overrideRange($singleVariableIndex, $singleVariableIndex, [ new Token([T_CURLY_OPEN, '{']), diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocClosingMarkerFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocClosingMarkerFixer.php new file mode 100644 index 00000000..a4245c9f --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocClosingMarkerFixer.php @@ -0,0 +1,188 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\StringNotation; + +use PhpCsFixer\AbstractFixer; +use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; +use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * @author Michael Vorisek + */ +final class HeredocClosingMarkerFixer extends AbstractFixer implements ConfigurableFixerInterface +{ + /** + * @var list + */ + public const RESERVED_CLOSING_MARKERS = [ + 'CSS', + 'DIFF', + 'HTML', + 'JS', + 'JSON', + 'MD', + 'PHP', + 'PYTHON', + 'RST', + 'TS', + 'SQL', + 'XML', + 'YAML', + ]; + + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'Unify `heredoc` or `nowdoc` closing marker.', + [ + new CodeSample( + <<<'EOD' + 'EOF'] + ), + new CodeSample( + <<<'EOD_' + true] + ), + ] + ); + } + + public function isCandidate(Tokens $tokens): bool + { + return $tokens->isTokenKindFound(T_START_HEREDOC); + } + + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface + { + return new FixerConfigurationResolver([ + (new FixerOptionBuilder( + 'closing_marker', + 'Preferred closing marker.' + )) + ->setAllowedTypes(['string']) + ->setDefault('EOD') + ->getOption(), + (new FixerOptionBuilder( + 'reserved_closing_markers', + 'Reserved closing markers to be kept unchanged.' + )) + ->setAllowedTypes(['array']) + ->setDefault(self::RESERVED_CLOSING_MARKERS) + ->getOption(), + (new FixerOptionBuilder( + 'explicit_heredoc_style', + 'Whether the closing marker should be wrapped in double quotes.' + )) + ->setAllowedTypes(['bool']) + ->setDefault(false) + ->getOption(), + ]); + } + + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void + { + $reservedClosingMarkersMap = null; + + $startIndex = null; + foreach ($tokens as $index => $token) { + if ($token->isGivenKind(T_START_HEREDOC)) { + $startIndex = $index; + + continue; + } + + if (null !== $startIndex && $token->isGivenKind(T_END_HEREDOC)) { + $existingClosingMarker = trim($token->getContent()); + + if (null === $reservedClosingMarkersMap) { + $reservedClosingMarkersMap = []; + foreach ($this->configuration['reserved_closing_markers'] as $v) { + $reservedClosingMarkersMap[mb_strtoupper($v)] = $v; + } + } + + $existingClosingMarker = mb_strtoupper($existingClosingMarker); + do { + $newClosingMarker = $reservedClosingMarkersMap[$existingClosingMarker] ?? null; + if (!str_ends_with($existingClosingMarker, '_')) { + break; + } + $existingClosingMarker = substr($existingClosingMarker, 0, -1); + } while (null === $newClosingMarker); + + if (null === $newClosingMarker) { + $newClosingMarker = $this->configuration['closing_marker']; + } + + $content = $tokens->generatePartialCode($startIndex + 1, $index - 1); + while (Preg::match('~(^|[\r\n])\s*'.preg_quote($newClosingMarker, '~').'(?!\w)~', $content)) { + $newClosingMarker .= '_'; + } + + [$tokens[$startIndex], $tokens[$index]] = $this->convertClosingMarker($tokens[$startIndex], $token, $newClosingMarker); + + $startIndex = null; + + continue; + } + } + } + + /** + * @return array{Token, Token} + */ + private function convertClosingMarker(Token $startToken, Token $endToken, string $newClosingMarker): array + { + $isNowdoc = str_contains($startToken->getContent(), '\''); + + $markerQuote = $isNowdoc + ? '\'' + : (true === $this->configuration['explicit_heredoc_style'] ? '"' : ''); + + return [new Token([ + $startToken->getId(), + Preg::replace('/<<<\h*\K["\']?[^\s"\']+["\']?/', $markerQuote.$newClosingMarker.$markerQuote, $startToken->getContent()), + ]), new Token([ + $endToken->getId(), + Preg::replace('/\S+/', $newClosingMarker, $endToken->getContent()), + ])]; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocToNowdocFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocToNowdocFixer.php index 88add2d5..9c736c14 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocToNowdocFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/HeredocToNowdocFixer.php @@ -47,7 +47,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run after EscapeImplicitBackslashesFixer. + * Must run after EscapeImplicitBackslashesFixer, StringImplicitBackslashesFixer. */ public function getPriority(): int { @@ -81,12 +81,12 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $content = $tokens[$index + 1]->getContent(); // regex: odd number of backslashes, not followed by dollar - if (Preg::match('/(?convertToNowdoc($token); - $content = str_replace(['\\\\', '\\$'], ['\\', '$'], $content); + $content = str_replace(['\\\\', '\$'], ['\\', '$'], $content); $tokens[$index + 1] = new Token([ $tokens[$index + 1]->getId(), $content, diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/MultilineStringToHeredocFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/MultilineStringToHeredocFixer.php new file mode 100644 index 00000000..1a6790e6 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/MultilineStringToHeredocFixer.php @@ -0,0 +1,166 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\StringNotation; + +use PhpCsFixer\AbstractFixer; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * @author Michael Vorisek + */ +final class MultilineStringToHeredocFixer extends AbstractFixer +{ + public function getDefinition(): FixerDefinitionInterface + { + return new FixerDefinition( + 'Convert multiline string to `heredoc` or `nowdoc`.', + [ + new CodeSample( + <<<'EOD' + getName()}"; + EOD."\n" + ), + ] + ); + } + + public function isCandidate(Tokens $tokens): bool + { + return $tokens->isAnyTokenKindsFound([T_CONSTANT_ENCAPSED_STRING, T_ENCAPSED_AND_WHITESPACE]); + } + + /** + * {@inheritdoc} + * + * Must run before EscapeImplicitBackslashesFixer, HeredocIndentationFixer, StringImplicitBackslashesFixer. + */ + public function getPriority(): int + { + return 16; + } + + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void + { + $inHeredoc = false; + $complexStringStartIndex = null; + foreach ($tokens as $index => $token) { + if ($token->isGivenKind([T_START_HEREDOC, T_END_HEREDOC])) { + $inHeredoc = $token->isGivenKind(T_START_HEREDOC) || !$token->isGivenKind(T_END_HEREDOC); + + continue; + } + + if (null === $complexStringStartIndex) { + if ($token->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) { + $this->convertStringToHeredoc($tokens, $index, $index); + + // skip next 2 added tokens if replaced + if ($tokens[$index]->isGivenKind(T_START_HEREDOC)) { + $inHeredoc = true; + } + } elseif ($token->equalsAny(['"', 'b"', 'B"'])) { + $complexStringStartIndex = $index; + } + } elseif ($token->equals('"')) { + $this->convertStringToHeredoc($tokens, $complexStringStartIndex, $index); + + $complexStringStartIndex = null; + } + } + } + + private function convertStringToHeredoc(Tokens $tokens, int $stringStartIndex, int $stringEndIndex): void + { + $closingMarker = 'EOD'; + + if ($tokens[$stringStartIndex]->isGivenKind(T_CONSTANT_ENCAPSED_STRING)) { + $content = $tokens[$stringStartIndex]->getContent(); + if ('b' === strtolower(substr($content, 0, 1))) { + $content = substr($content, 1); + } + $isSingleQuoted = str_starts_with($content, '\''); + $content = substr($content, 1, -1); + + if ($isSingleQuoted) { + $content = Preg::replace('~\\\([\\\\\'])~', '$1', $content); + } else { + $content = Preg::replace('~(\\\\\\\)|\\\(")~', '$1$2', $content); + } + + $constantStringToken = new Token([T_ENCAPSED_AND_WHITESPACE, $content."\n"]); + } else { + $content = $tokens->generatePartialCode($stringStartIndex + 1, $stringEndIndex - 1); + $isSingleQuoted = false; + $constantStringToken = null; + } + + if (!str_contains($content, "\n") && !str_contains($content, "\r")) { + return; + } + + while (Preg::match('~(^|[\r\n])\s*'.preg_quote($closingMarker, '~').'(?!\w)~', $content)) { + $closingMarker .= '_'; + } + + $quoting = $isSingleQuoted ? '\'' : ''; + $heredocStartToken = new Token([T_START_HEREDOC, '<<<'.$quoting.$closingMarker.$quoting."\n"]); + $heredocEndToken = new Token([T_END_HEREDOC, $closingMarker]); + + if (null !== $constantStringToken) { + $tokens->overrideRange($stringStartIndex, $stringEndIndex, [ + $heredocStartToken, + $constantStringToken, + $heredocEndToken, + ]); + } else { + for ($i = $stringStartIndex + 1; $i < $stringEndIndex; ++$i) { + if ($tokens[$i]->isGivenKind(T_ENCAPSED_AND_WHITESPACE)) { + $tokens[$i] = new Token([ + $tokens[$i]->getId(), + Preg::replace('~(\\\\\\\)|\\\(")~', '$1$2', $tokens[$i]->getContent()), + ]); + } + } + + $tokens[$stringStartIndex] = $heredocStartToken; + $tokens[$stringEndIndex] = $heredocEndToken; + if ($tokens[$stringEndIndex - 1]->isGivenKind(T_ENCAPSED_AND_WHITESPACE)) { + $tokens[$stringEndIndex - 1] = new Token([ + $tokens[$stringEndIndex - 1]->getId(), + $tokens[$stringEndIndex - 1]->getContent()."\n", + ]); + } else { + $tokens->insertAt($stringEndIndex, new Token([ + T_ENCAPSED_AND_WHITESPACE, + "\n", + ])); + } + } + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SimpleToComplexStringVariableFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SimpleToComplexStringVariableFixer.php index 75891ac0..efb139ca 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SimpleToComplexStringVariableFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SimpleToComplexStringVariableFixer.php @@ -94,8 +94,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $tokenOfStringBeforeToken = $tokens[$index - 1]; $stringContent = $tokenOfStringBeforeToken->getContent(); - if (str_ends_with($stringContent, '$') && !str_ends_with($stringContent, '\\$')) { - $newContent = substr($stringContent, 0, -1).'\\$'; + if (str_ends_with($stringContent, '$') && !str_ends_with($stringContent, '\$')) { + $newContent = substr($stringContent, 0, -1).'\$'; $tokenOfStringBeforeToken = new Token([T_ENCAPSED_AND_WHITESPACE, $newContent]); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SingleQuoteFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SingleQuoteFixer.php index ab3d7ddd..10698a69 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SingleQuoteFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/StringNotation/SingleQuoteFixer.php @@ -57,7 +57,7 @@ public function getDefinition(): FixerDefinitionInterface * {@inheritdoc} * * Must run before NoUselessConcatOperatorFixer. - * Must run after BacktickToShellExecFixer, EscapeImplicitBackslashesFixer. + * Must run after BacktickToShellExecFixer, EscapeImplicitBackslashesFixer, StringImplicitBackslashesFixer. */ public function getPriority(): int { @@ -88,10 +88,10 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void '"' === $content[0] && (true === $this->configuration['strings_containing_single_quote_chars'] || !str_contains($content, "'")) // regex: odd number of backslashes, not followed by double quote or dollar - && !Preg::match('/(? + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Fixer\StringNotation; + +use PhpCsFixer\AbstractFixer; +use PhpCsFixer\Fixer\ConfigurableFixerInterface; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; +use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; +use PhpCsFixer\FixerDefinition\CodeSample; +use PhpCsFixer\FixerDefinition\FixerDefinition; +use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * @author Filippo Tessarotto + * @author Michael Vorisek + */ +final class StringImplicitBackslashesFixer extends AbstractFixer implements ConfigurableFixerInterface +{ + public function getDefinition(): FixerDefinitionInterface + { + $codeSample = <<<'EOF' + 'escape'] + ), + new CodeSample( + $codeSample, + ['double_quoted' => 'unescape'] + ), + new CodeSample( + $codeSample, + ['heredoc' => 'unescape'] + ), + ], + 'In PHP double-quoted strings and heredocs some chars like `n`, `$` or `u` have special meanings if preceded by a backslash ' + .'(and some are special only if followed by other special chars), while a backslash preceding other chars are interpreted like a plain ' + .'backslash. The precise list of those special chars is hard to remember and to identify quickly: this fixer escapes backslashes ' + ."that do not start a special interpretation with the char after them.\n" + .'It is possible to fix also single-quoted strings: in this case there is no special chars apart from single-quote and backslash ' + .'itself, so the fixer simply ensure that all backslashes are escaped. Both single and double backslashes are allowed in single-quoted ' + .'strings, so the purpose in this context is mainly to have a uniformed way to have them written all over the codebase.' + ); + } + + public function isCandidate(Tokens $tokens): bool + { + return $tokens->isAnyTokenKindsFound([T_ENCAPSED_AND_WHITESPACE, T_CONSTANT_ENCAPSED_STRING]); + } + + /** + * {@inheritdoc} + * + * Must run before HeredocToNowdocFixer, SingleQuoteFixer. + * Must run after BacktickToShellExecFixer, MultilineStringToHeredocFixer. + */ + public function getPriority(): int + { + return 15; + } + + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void + { + $singleQuotedReservedRegex = '[\'\\\]'; + $doubleQuotedReservedRegex = '(?:[efnrtv$"\\\0-7]|x[0-9A-Fa-f]|u{|$)'; + $heredocSyntaxReservedRegex = '(?:[efnrtv$\\\0-7]|x[0-9A-Fa-f]|u{|$)'; + + $doubleQuoteOpened = false; + foreach ($tokens as $index => $token) { + if ($token->equalsAny(['"', 'b"', 'B"'])) { + $doubleQuoteOpened = !$doubleQuoteOpened; + } + + if (!$token->isGivenKind([T_ENCAPSED_AND_WHITESPACE, T_CONSTANT_ENCAPSED_STRING])) { + continue; + } + + $content = $token->getContent(); + if (!str_contains($content, '\\')) { + continue; + } + + // nowdoc syntax + if ($token->isGivenKind(T_ENCAPSED_AND_WHITESPACE) && '\'' === substr(rtrim($tokens[$index - 1]->getContent()), -1)) { + continue; + } + + $firstTwoCharacters = strtolower(substr($content, 0, 2)); + $isSingleQuotedString = $token->isGivenKind(T_CONSTANT_ENCAPSED_STRING) && ('\'' === $content[0] || 'b\'' === $firstTwoCharacters); + $isDoubleQuotedString = + ($token->isGivenKind(T_CONSTANT_ENCAPSED_STRING) && ('"' === $content[0] || 'b"' === $firstTwoCharacters)) + || ($token->isGivenKind(T_ENCAPSED_AND_WHITESPACE) && $doubleQuoteOpened); + + if ($isSingleQuotedString + ? 'ignore' === $this->configuration['single_quoted'] + : ($isDoubleQuotedString + ? 'ignore' === $this->configuration['double_quoted'] + : 'ignore' === $this->configuration['heredoc']) + ) { + continue; + } + + $escapeBackslashes = $isSingleQuotedString + ? 'escape' === $this->configuration['single_quoted'] + : ($isDoubleQuotedString + ? 'escape' === $this->configuration['double_quoted'] + : 'escape' === $this->configuration['heredoc']); + + $reservedRegex = $isSingleQuotedString + ? $singleQuotedReservedRegex + : ($isDoubleQuotedString + ? $doubleQuotedReservedRegex + : $heredocSyntaxReservedRegex); + + if ($escapeBackslashes) { + $regex = '/(?getId(), $newContent]); + } + } + } + + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface + { + return new FixerConfigurationResolver([ + (new FixerOptionBuilder('single_quoted', 'Whether to escape backslashes in single-quoted strings.')) + ->setAllowedValues(['escape', 'unescape', 'ignore']) + ->setDefault('unescape') + ->getOption(), + (new FixerOptionBuilder('double_quoted', 'Whether to escape backslashes in double-quoted strings.')) + ->setAllowedValues(['escape', 'unescape', 'ignore']) + ->setDefault('escape') + ->getOption(), + (new FixerOptionBuilder('heredoc', 'Whether to escape backslashes in heredoc syntax.')) + ->setAllowedValues(['escape', 'unescape', 'ignore']) + ->setDefault('escape') + ->getOption(), + ]); + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/BlankLineBetweenImportGroupsFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/BlankLineBetweenImportGroupsFixer.php index 1976aefb..7bd48ca6 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/BlankLineBetweenImportGroupsFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/BlankLineBetweenImportGroupsFixer.php @@ -111,7 +111,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } /** - * @param int[] $uses + * @param list $uses */ private function walkOverUses(Tokens $tokens, array $uses): void { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/HeredocIndentationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/HeredocIndentationFixer.php index c526d6dd..4babba28 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/HeredocIndentationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/HeredocIndentationFixer.php @@ -72,7 +72,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run after BracesFixer, StatementIndentationFixer. + * Must run after BracesFixer, MultilineStringToHeredocFixer, StatementIndentationFixer. */ public function getPriority(): int { @@ -127,7 +127,9 @@ private function fixIndentation(Tokens $tokens, int $start, int $end): void return; } - for ($index = $end - 1, $last = true; $index > $start; --$index, $last = false) { + $index = $end - 1; + + for ($last = true; $index > $start; --$index, $last = false) { if (!$tokens[$index]->isGivenKind([T_ENCAPSED_AND_WHITESPACE, T_WHITESPACE])) { continue; } @@ -138,7 +140,7 @@ private function fixIndentation(Tokens $tokens, int $start, int $end): void $content = Preg::replace('/(?<=\v)(?!'.$currentIndent.')\h+/', '', $content); } - $regexEnd = $last && !$currentIndent ? '(?!\v|$)' : '(?!\v)'; + $regexEnd = $last && '' === $currentIndent ? '(?!\v|$)' : '(?!\v)'; $content = Preg::replace('/(?<=\v)'.$currentIndent.$regexEnd.'/', $indent, $content); $tokens[$index] = new Token([$tokens[$index]->getId(), $content]); @@ -154,9 +156,9 @@ private function fixIndentation(Tokens $tokens, int $start, int $end): void $content = $tokens[$index]->getContent(); - if (!\in_array($content[0], ["\r", "\n"], true) && (!$currentIndent || str_starts_with($content, $currentIndent))) { + if (!\in_array($content[0], ["\r", "\n"], true) && ('' === $currentIndent || str_starts_with($content, $currentIndent))) { $content = $indent.substr($content, $currentIndentLength); - } elseif ($currentIndent) { + } elseif ('' !== $currentIndent) { $content = Preg::replace('/^(?!'.$currentIndent.')\h+/', '', $content); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/MethodChainingIndentationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/MethodChainingIndentationFixer.php index 2830246a..dc7fff6e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/MethodChainingIndentationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/MethodChainingIndentationFixer.php @@ -36,6 +36,16 @@ public function getDefinition(): FixerDefinitionInterface ); } + /** + * {@inheritdoc} + * + * Must run after NoSpaceAroundDoubleColonFixer. + */ + public function getPriority(): int + { + return 0; + } + public function isCandidate(Tokens $tokens): bool { return $tokens->isAnyTokenKindsFound(Token::getObjectOperatorKinds()); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php index 996d13f1..29196ba1 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoExtraBlankLinesFixer.php @@ -25,6 +25,7 @@ use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Analyzer\SwitchAnalyzer; use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; @@ -37,7 +38,7 @@ final class NoExtraBlankLinesFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { /** - * @var string[] + * @var list */ private static array $availableTokens = [ 'attribute', @@ -57,12 +58,12 @@ final class NoExtraBlankLinesFixer extends AbstractFixer implements Configurable ]; /** - * @var array key is token id, value is name of callback + * @var array key is token id */ private array $tokenKindCallbackMap; /** - * @var array token prototype, value is name of callback + * @var array key is token's content */ private array $tokenEqualsMap; @@ -83,26 +84,27 @@ public function configure(array $configuration): void $this->tokenEqualsMap = []; if (\in_array('curly_brace_block', $tokensConfiguration, true)) { - $this->tokenEqualsMap['{'] = 'fixStructureOpenCloseIfMultiLine'; // i.e. not: CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN + $this->tokenEqualsMap['{'] = [$this, 'fixStructureOpenCloseIfMultiLine']; // i.e. not: CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN } if (\in_array('parenthesis_brace_block', $tokensConfiguration, true)) { - $this->tokenEqualsMap['('] = 'fixStructureOpenCloseIfMultiLine'; // i.e. not: CT::T_BRACE_CLASS_INSTANTIATION_OPEN + $this->tokenEqualsMap['('] = [$this, 'fixStructureOpenCloseIfMultiLine']; // i.e. not: CT::T_BRACE_CLASS_INSTANTIATION_OPEN } - static $configMap = [ - 'attribute' => [CT::T_ATTRIBUTE_CLOSE, 'fixAfterToken'], - 'break' => [T_BREAK, 'fixAfterToken'], - 'case' => [T_CASE, 'fixAfterCaseToken'], - 'continue' => [T_CONTINUE, 'fixAfterToken'], - 'default' => [T_DEFAULT, 'fixAfterToken'], - 'extra' => [T_WHITESPACE, 'removeMultipleBlankLines'], - 'return' => [T_RETURN, 'fixAfterToken'], - 'square_brace_block' => [CT::T_ARRAY_SQUARE_BRACE_OPEN, 'fixStructureOpenCloseIfMultiLine'], - 'switch' => [T_SWITCH, 'fixAfterToken'], - 'throw' => [T_THROW, 'fixAfterThrowToken'], - 'use' => [T_USE, 'removeBetweenUse'], - 'use_trait' => [CT::T_USE_TRAIT, 'removeBetweenUse'], + // Each item requires explicit array-like callable, otherwise PHPStan will complain about unused private methods. + $configMap = [ + 'attribute' => [CT::T_ATTRIBUTE_CLOSE, [$this, 'fixAfterToken']], + 'break' => [T_BREAK, [$this, 'fixAfterToken']], + 'case' => [T_CASE, [$this, 'fixAfterCaseToken']], + 'continue' => [T_CONTINUE, [$this, 'fixAfterToken']], + 'default' => [T_DEFAULT, [$this, 'fixAfterToken']], + 'extra' => [T_WHITESPACE, [$this, 'removeMultipleBlankLines']], + 'return' => [T_RETURN, [$this, 'fixAfterToken']], + 'square_brace_block' => [CT::T_ARRAY_SQUARE_BRACE_OPEN, [$this, 'fixStructureOpenCloseIfMultiLine']], + 'switch' => [T_SWITCH, [$this, 'fixAfterToken']], + 'throw' => [T_THROW, [$this, 'fixAfterThrowToken']], + 'use' => [T_USE, [$this, 'removeBetweenUse']], + 'use_trait' => [CT::T_USE_TRAIT, [$this, 'removeBetweenUse']], ]; $this->tokenKindCallbackMap = []; @@ -288,6 +290,14 @@ protected function createConfigurationDefinition(): FixerConfigurationResolverIn ]); } + /** + * @uses fixAfterToken() + * @uses fixAfterCaseToken() + * @uses fixAfterThrowToken() + * @uses fixStructureOpenCloseIfMultiLine() + * @uses removeBetweenUse() + * @uses removeMultipleBlankLines() + */ private function fixByToken(Token $token, int $index): void { foreach ($this->tokenKindCallbackMap as $kind => $callback) { @@ -295,7 +305,7 @@ private function fixByToken(Token $token, int $index): void continue; } - $this->{$callback}($index); + \call_user_func_array($this->tokenKindCallbackMap[$token->getId()], [$index]); return; } @@ -305,7 +315,7 @@ private function fixByToken(Token $token, int $index): void continue; } - $this->{$callback}($index); + \call_user_func_array($this->tokenEqualsMap[$token->getContent()], [$index]); return; } @@ -374,9 +384,17 @@ private function fixAfterCaseToken(int $index): void private function fixAfterThrowToken(int $index): void { - if ($this->tokens[$this->tokens->getPrevMeaningfulToken($index)]->equalsAny([';', '{', '}', ':', [T_OPEN_TAG]])) { - $this->fixAfterToken($index); + $prevIndex = $this->tokens->getPrevMeaningfulToken($index); + + if (!$this->tokens[$prevIndex]->equalsAny([';', '{', '}', ':', [T_OPEN_TAG]])) { + return; } + + if ($this->tokens[$prevIndex]->equals(':') && !SwitchAnalyzer::belongsToSwitch($this->tokens, $prevIndex)) { + return; + } + + $this->fixAfterToken($index); } /** diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoTrailingWhitespaceFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoTrailingWhitespaceFixer.php index c21ff39f..e05a9fdd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoTrailingWhitespaceFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoTrailingWhitespaceFixer.php @@ -76,7 +76,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - $lines = Preg::split('/(\\R+)/', $token->getContent(), -1, PREG_SPLIT_DELIM_CAPTURE); + $lines = Preg::split('/(\R+)/', $token->getContent(), -1, PREG_SPLIT_DELIM_CAPTURE); $linesSize = \count($lines); // fix only multiline whitespaces or singleline whitespaces at the end of file diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoWhitespaceInBlankLineFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoWhitespaceInBlankLineFixer.php index 60217e17..352ce7a8 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoWhitespaceInBlankLineFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/NoWhitespaceInBlankLineFixer.php @@ -38,7 +38,7 @@ public function getDefinition(): FixerDefinitionInterface /** * {@inheritdoc} * - * Must run after AssignNullCoalescingToCoalesceEqualFixer, CombineConsecutiveIssetsFixer, CombineConsecutiveUnsetsFixer, FunctionToConstantFixer, NoEmptyCommentFixer, NoEmptyPhpdocFixer, NoEmptyStatementFixer, NoUselessElseFixer, NoUselessReturnFixer, YieldFromArrayToYieldsFixer. + * Must run after AssignNullCoalescingToCoalesceEqualFixer, CombineConsecutiveIssetsFixer, CombineConsecutiveUnsetsFixer, FunctionToConstantFixer, NoEmptyCommentFixer, NoEmptyStatementFixer, NoUselessElseFixer, NoUselessReturnFixer, YieldFromArrayToYieldsFixer. */ public function getPriority(): int { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/SpacesInsideParenthesesFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/SpacesInsideParenthesesFixer.php index cf862876..a5da0b86 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/SpacesInsideParenthesesFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/SpacesInsideParenthesesFixer.php @@ -76,14 +76,14 @@ public function getPriority(): int public function isCandidate(Tokens $tokens): bool { - return $tokens->isTokenKindFound('('); + return $tokens->isAnyTokenKindsFound(['(', CT::T_BRACE_CLASS_INSTANTIATION_OPEN]); } protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { if ('none' === $this->configuration['space']) { foreach ($tokens as $index => $token) { - if (!$token->equals('(')) { + if (!$token->equalsAny(['(', [CT::T_BRACE_CLASS_INSTANTIATION_OPEN]])) { continue; } @@ -94,7 +94,8 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); + $blockType = Tokens::detectBlockType($tokens[$index]); + $endIndex = $tokens->findBlockEnd($blockType['type'], $index); // remove space after opening `(` if (!$tokens[$tokens->getNextNonWhitespace($index)]->isComment()) { @@ -110,11 +111,12 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void if ('single' === $this->configuration['space']) { foreach ($tokens as $index => $token) { - if (!$token->equals('(')) { + if (!$token->equalsAny(['(', [CT::T_BRACE_CLASS_INSTANTIATION_OPEN]])) { continue; } - $endParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); + $blockType = Tokens::detectBlockType($tokens[$index]); + $endParenthesisIndex = $tokens->findBlockEnd($blockType['type'], $index); // if not other content than spaces in block remove spaces $blockContent = $this->getBlockContent($index, $endParenthesisIndex, $tokens); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/StatementIndentationFixer.php b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/StatementIndentationFixer.php index d22d50dd..ca448fb4 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/StatementIndentationFixer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Fixer/Whitespace/StatementIndentationFixer.php @@ -15,8 +15,12 @@ namespace PhpCsFixer\Fixer\Whitespace; use PhpCsFixer\AbstractFixer; +use PhpCsFixer\Fixer\ConfigurableFixerInterface; use PhpCsFixer\Fixer\Indentation; use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver; +use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface; +use PhpCsFixer\FixerConfiguration\FixerOptionBuilder; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; @@ -26,7 +30,7 @@ use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; -final class StatementIndentationFixer extends AbstractFixer implements WhitespacesAwareFixerInterface +final class StatementIndentationFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface { use Indentation; @@ -56,6 +60,35 @@ public function getDefinition(): FixerDefinitionInterface } ' ), + new CodeSample( + ' false] + ), + new CodeSample( + ' true] + ), ] ); } @@ -64,7 +97,7 @@ public function getDefinition(): FixerDefinitionInterface * {@inheritdoc} * * Must run before HeredocIndentationFixer. - * Must run after BracesPositionFixer, ClassAttributesSeparationFixer, CurlyBracesPositionFixer, MethodArgumentSpaceFixer, NoUselessElseFixer, YieldFromArrayToYieldsFixer. + * Must run after BracesPositionFixer, ClassAttributesSeparationFixer, CurlyBracesPositionFixer, FullyQualifiedStrictTypesFixer, GlobalNamespaceImportFixer, MethodArgumentSpaceFixer, NoUselessElseFixer, YieldFromArrayToYieldsFixer. */ public function getPriority(): int { @@ -76,6 +109,16 @@ public function isCandidate(Tokens $tokens): bool return true; } + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface + { + return new FixerConfigurationResolver([ + (new FixerOptionBuilder('stick_comment_to_next_continuous_control_statement', 'Last comment of code block counts as comment for next block.')) + ->setAllowedTypes(['bool']) + ->setDefault(false) + ->getOption(), + ]); + } + protected function applyFix(\SplFileInfo $file, Tokens $tokens): void { $this->alternativeSyntaxAnalyzer = new AlternativeSyntaxAnalyzer(); @@ -88,6 +131,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void T_FOR, T_FOREACH, T_WHILE, + T_DO, T_SWITCH, T_CASE, T_DEFAULT, @@ -97,6 +141,16 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void T_TRAIT, T_EXTENDS, T_IMPLEMENTS, + T_CONST, + ]; + $controlStructurePossibiblyWithoutBracesTokens = [ + T_IF, + T_ELSE, + T_ELSEIF, + T_FOR, + T_FOREACH, + T_WHILE, + T_DO, ]; if (\defined('T_MATCH')) { // @TODO: drop condition when PHP 8.0+ is required $blockSignatureFirstTokens[] = T_MATCH; @@ -118,20 +172,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $this->extractIndent($this->computeNewLineContent($tokens, 0)), ); - $methodModifierTokens = [ - // https://github.com/php/php-langspec/blob/master/spec/19-grammar.md#grammar-visibility-modifier - T_PUBLIC, - T_PROTECTED, - T_PRIVATE, - // https://github.com/php/php-langspec/blob/master/spec/19-grammar.md#grammar-static-modifier - T_STATIC, - // https://github.com/php/php-langspec/blob/master/spec/19-grammar.md#grammar-class-modifier - T_ABSTRACT, - T_FINAL, - ]; - - $methodModifierIndents = []; - /** * @var list $scopes */ @@ -155,12 +196,25 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $previousLineInitialIndent = ''; $previousLineNewIndent = ''; + $noBracesBlockStarts = []; $alternativeBlockStarts = []; $caseBlockStarts = []; foreach ($tokens as $index => $token) { $currentScope = \count($scopes) - 1; + if (isset($noBracesBlockStarts[$index])) { + $scopes[] = [ + 'type' => 'block', + 'skip' => false, + 'end_index' => $this->findStatementEndIndex($tokens, $index, \count($tokens) - 1), + 'end_index_inclusive' => true, + 'initial_indent' => $this->getLineIndentationWithBracesCompatibility($tokens, $index, $lastIndent), + 'is_indented_block' => true, + ]; + ++$currentScope; + } + if ( $token->equalsAny($blockFirstTokens) || ($token->equals('(') && !$tokens[$tokens->getPrevMeaningfulToken($index)]->isGivenKind(T_ARRAY)) @@ -176,7 +230,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void } elseif ($token->equals(':')) { if (isset($caseBlockStarts[$index])) { [$endIndex, $endIndexInclusive] = $this->findCaseBlockEnd($tokens, $index); - } else { + } elseif ($this->alternativeSyntaxAnalyzer->belongsToAlternativeSyntax($tokens, $index)) { $endIndex = $this->alternativeSyntaxAnalyzer->findAlternativeSyntaxBlockEnd($tokens, $alternativeBlockStarts[$index]); } } elseif ($token->isGivenKind(CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN)) { @@ -227,19 +281,45 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void continue; } - if ($token->isGivenKind($blockSignatureFirstTokens)) { + if ( + $token->isGivenKind(CT::T_ARRAY_SQUARE_BRACE_OPEN) + || ($token->equals('(') && $tokens[$tokens->getPrevMeaningfulToken($index)]->isGivenKind(T_ARRAY)) + ) { + $blockType = $token->equals('(') ? Tokens::BLOCK_TYPE_PARENTHESIS_BRACE : Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE; + + $scopes[] = [ + 'type' => 'statement', + 'skip' => true, + 'end_index' => $tokens->findBlockEnd($blockType, $index), + 'end_index_inclusive' => true, + 'initial_indent' => $previousLineInitialIndent, + 'new_indent' => $previousLineNewIndent, + 'is_indented_block' => false, + ]; + + continue; + } + + $isPropertyStart = $this->isPropertyStart($tokens, $index); + if ($isPropertyStart || $token->isGivenKind($blockSignatureFirstTokens)) { + $lastWhitespaceIndex = null; + $closingParenthesisIndex = null; + for ($endIndex = $index + 1, $max = \count($tokens); $endIndex < $max; ++$endIndex) { - if ($tokens[$endIndex]->equals('(')) { - $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $endIndex); + $endToken = $tokens[$endIndex]; + + if ($endToken->equals('(')) { + $closingParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $endIndex); + $endIndex = $closingParenthesisIndex; continue; } - if ($tokens[$endIndex]->equalsAny(['{', ';', [T_DOUBLE_ARROW], [T_IMPLEMENTS]])) { + if ($endToken->equalsAny(['{', ';', [T_DOUBLE_ARROW], [T_IMPLEMENTS]])) { break; } - if ($tokens[$endIndex]->equals(':')) { + if ($endToken->equals(':')) { if ($token->isGivenKind([T_CASE, T_DEFAULT])) { $caseBlockStarts[$endIndex] = $index; } else { @@ -248,6 +328,25 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void break; } + + if (!$token->isGivenKind($controlStructurePossibiblyWithoutBracesTokens)) { + continue; + } + + if ($endToken->isWhitespace()) { + $lastWhitespaceIndex = $endIndex; + + continue; + } + + if (!$endToken->isComment()) { + $noBraceBlockStartIndex = $lastWhitespaceIndex ?? $endIndex; + $noBracesBlockStarts[$noBraceBlockStartIndex] = true; + + $endIndex = $closingParenthesisIndex ?? $index; + + break; + } } $scopes[] = [ @@ -256,30 +355,13 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void 'end_index' => $endIndex, 'end_index_inclusive' => true, 'initial_indent' => $this->getLineIndentationWithBracesCompatibility($tokens, $index, $lastIndent), - 'is_indented_block' => $token->isGivenKind([T_EXTENDS, T_IMPLEMENTS]), + 'is_indented_block' => $isPropertyStart || $token->isGivenKind([T_EXTENDS, T_IMPLEMENTS, T_CONST]), ]; continue; } - if ($token->isGivenKind($methodModifierTokens)) { - $methodModifierIndents[$index] = $lastIndent; - - continue; - } - if ($token->isGivenKind(T_FUNCTION)) { - $x = $tokens->getPrevMeaningfulToken($index); - while ( - null !== $x - && $tokens[$x]->isGivenKind($methodModifierTokens) - && \array_key_exists($x, $methodModifierIndents) - ) { - $lastIndent = $methodModifierIndents[$x]; - $x = $tokens->getPrevMeaningfulToken($x); - } - - $methodModifierIndents = []; $endIndex = $index + 1; for ($max = \count($tokens); $endIndex < $max; ++$endIndex) { @@ -300,7 +382,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void 'end_index' => $endIndex, 'end_index_inclusive' => true, 'initial_indent' => $this->getLineIndentationWithBracesCompatibility($tokens, $index, $lastIndent), - 'is_indented_block' => $token->isGivenKind([T_EXTENDS, T_IMPLEMENTS]), + 'is_indented_block' => false, ]; continue; @@ -383,7 +465,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void $nextNextIndex = $tokens->getNextMeaningfulToken($nextIndex); if (null !== $nextNextIndex && $tokens[$nextNextIndex]->isGivenKind([T_ELSE, T_ELSEIF])) { - $indent = false; + $indent = true !== $this->configuration['stick_comment_to_next_continuous_control_statement']; } else { $indent = true; } @@ -477,6 +559,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void 'end_index_inclusive' => false, 'initial_indent' => $previousLineInitialIndent, 'new_indent' => $previousLineNewIndent, + 'is_indented_block' => true, ]; } } @@ -486,9 +569,26 @@ private function findStatementEndIndex(Tokens $tokens, int $index, int $parentSc { $endIndex = null; + $ifLevel = 0; + $doWhileLevel = 0; for ($searchEndIndex = $index; $searchEndIndex <= $parentScopeEndIndex; ++$searchEndIndex) { $searchEndToken = $tokens[$searchEndIndex]; + if ( + $searchEndToken->isGivenKind(T_IF) + && !$tokens[$tokens->getPrevMeaningfulToken($searchEndIndex)]->isGivenKind(T_ELSE) + ) { + ++$ifLevel; + + continue; + } + + if ($searchEndToken->isGivenKind(T_DO)) { + ++$doWhileLevel; + + continue; + } + if ($searchEndToken->equalsAny(['(', '{', [CT::T_ARRAY_SQUARE_BRACE_OPEN]])) { if ($searchEndToken->equals('(')) { $blockType = Tokens::BLOCK_TYPE_PARENTHESIS_BRACE; @@ -499,15 +599,46 @@ private function findStatementEndIndex(Tokens $tokens, int $index, int $parentSc } $searchEndIndex = $tokens->findBlockEnd($blockType, $searchEndIndex); + $searchEndToken = $tokens[$searchEndIndex]; + } + if (!$searchEndToken->equalsAny([';', ',', '}', [T_CLOSE_TAG]])) { continue; } - if ($searchEndToken->equalsAny([';', ',', '}', [T_CLOSE_TAG]])) { - $endIndex = $tokens->getPrevNonWhitespace($searchEndIndex); + $controlStructureContinuationIndex = $tokens->getNextMeaningfulToken($searchEndIndex); - break; + if ( + $ifLevel > 0 + && null !== $controlStructureContinuationIndex + && $tokens[$controlStructureContinuationIndex]->isGivenKind([T_ELSE, T_ELSEIF]) + ) { + if ( + $tokens[$controlStructureContinuationIndex]->isGivenKind(T_ELSE) + && !$tokens[$tokens->getNextMeaningfulToken($controlStructureContinuationIndex)]->isGivenKind(T_IF) + ) { + --$ifLevel; + } + + $searchEndIndex = $controlStructureContinuationIndex; + + continue; + } + + if ( + $doWhileLevel > 0 + && null !== $controlStructureContinuationIndex + && $tokens[$controlStructureContinuationIndex]->isGivenKind([T_WHILE]) + ) { + --$doWhileLevel; + $searchEndIndex = $controlStructureContinuationIndex; + + continue; } + + $endIndex = $tokens->getPrevNonWhitespace($searchEndIndex); + + break; } return $endIndex ?? $tokens->getPrevMeaningfulToken($parentScopeEndIndex); @@ -570,6 +701,37 @@ private function getLineIndentationWithBracesCompatibility(Tokens $tokens, int $ return $regularIndent; } + /** + * Returns whether the token at given index is the last token in a property + * declaration before the type or the name of that property. + */ + private function isPropertyStart(Tokens $tokens, int $index): bool + { + $propertyKeywords = [T_VAR, T_PUBLIC, T_PROTECTED, T_PRIVATE, T_STATIC]; + if (\defined('T_READONLY')) { // @TODO: drop condition when PHP 8.1+ is required + $propertyKeywords[] = T_READONLY; + } + + $nextIndex = $tokens->getNextMeaningfulToken($index); + if ( + null === $nextIndex + || $tokens[$nextIndex]->isGivenKind($propertyKeywords) + || $tokens[$nextIndex]->isGivenKind([T_CONST, T_FUNCTION]) + ) { + return false; + } + + while ($tokens[$index]->isGivenKind($propertyKeywords)) { + if ($tokens[$index]->isGivenKind([T_VAR, T_PUBLIC, T_PROTECTED, T_PRIVATE])) { + return true; + } + + $index = $tokens->getPrevMeaningfulToken($index); + } + + return false; + } + /** * Returns whether the token at given index is a comment whose indentation * can be fixed. @@ -596,22 +758,22 @@ private function isCommentWithFixableIndentation(Tokens $tokens, int $index): bo $firstCommentIndex = $index; while (true) { - $i = $this->getSiblingContinuousSingleLineComment($tokens, $firstCommentIndex, false); - if (null === $i) { + $firstCommentCandidateIndex = $this->getSiblingContinuousSingleLineComment($tokens, $firstCommentIndex, false); + if (null === $firstCommentCandidateIndex) { break; } - $firstCommentIndex = $i; + $firstCommentIndex = $firstCommentCandidateIndex; } $lastCommentIndex = $index; while (true) { - $i = $this->getSiblingContinuousSingleLineComment($tokens, $lastCommentIndex, true); - if (null === $i) { + $lastCommentCandidateIndex = $this->getSiblingContinuousSingleLineComment($tokens, $lastCommentIndex, true); + if (null === $lastCommentCandidateIndex) { break; } - $lastCommentIndex = $i; + $lastCommentIndex = $lastCommentCandidateIndex; } if ($firstCommentIndex === $lastCommentIndex) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/FixerConfiguration/FixerOptionSorter.php b/vendor/friendsofphp/php-cs-fixer/src/FixerConfiguration/FixerOptionSorter.php index 9cd385a4..bb526874 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/FixerConfiguration/FixerOptionSorter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/FixerConfiguration/FixerOptionSorter.php @@ -30,7 +30,7 @@ public function sort(iterable $options): array $options = iterator_to_array($options, false); } - usort($options, static fn (FixerOptionInterface $a, FixerOptionInterface $b): int => strcmp($a->getName(), $b->getName())); + usort($options, static fn (FixerOptionInterface $a, FixerOptionInterface $b): int => $a->getName() <=> $b->getName()); return $options; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/FixerFactory.php b/vendor/friendsofphp/php-cs-fixer/src/FixerFactory.php index 7ee99bf2..214f8577 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/FixerFactory.php +++ b/vendor/friendsofphp/php-cs-fixer/src/FixerFactory.php @@ -83,25 +83,28 @@ public function registerBuiltInFixers(): self static $builtInFixers = null; if (null === $builtInFixers) { + /** @var list> */ $builtInFixers = []; /** @var SplFileInfo $file */ foreach (SymfonyFinder::create()->files()->in(__DIR__.'/Fixer')->name('*Fixer.php')->depth(1) as $file) { $relativeNamespace = $file->getRelativePath(); - $fixerClass = 'PhpCsFixer\\Fixer\\'.('' !== $relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php'); + $fixerClass = 'PhpCsFixer\Fixer\\'.('' !== $relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php'); $builtInFixers[] = $fixerClass; } } foreach ($builtInFixers as $class) { - $this->registerFixer(new $class(), false); + /** @var FixerInterface */ + $fixer = new $class(); + $this->registerFixer($fixer, false); } return $this; } /** - * @param FixerInterface[] $fixers + * @param iterable $fixers * * @return $this */ @@ -195,7 +198,7 @@ public function hasRule(string $name): bool } /** - * @return string[] + * @return list */ private function getFixersConflicts(FixerInterface $fixer): array { @@ -214,7 +217,7 @@ private function getFixersConflicts(FixerInterface $fixer): array } /** - * @param array $fixerConflicts + * @param array> $fixerConflicts */ private function generateConflictMessage(array $fixerConflicts): string { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Indicator/PhpUnitTestCaseIndicator.php b/vendor/friendsofphp/php-cs-fixer/src/Indicator/PhpUnitTestCaseIndicator.php index b4942d93..44d05c27 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Indicator/PhpUnitTestCaseIndicator.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Indicator/PhpUnitTestCaseIndicator.php @@ -65,7 +65,7 @@ public function isPhpUnitClass(Tokens $tokens, int $index): bool * Returns an indices of PHPUnit classes in reverse appearance order. * Order is important - it's reverted, so if we inject tokens into collection, * we do it for bottom of file first, and then to the top of the file, so we - * mitigate risk of not visiting whole collcetion (final indices). + * mitigate risk of not visiting whole collections (final indices). * * @return iterable array of [int start, int end] indices from later to earlier classes */ diff --git a/vendor/friendsofphp/php-cs-fixer/src/Linter/ProcessLinter.php b/vendor/friendsofphp/php-cs-fixer/src/Linter/ProcessLinter.php index 1808a17e..7dd42b78 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Linter/ProcessLinter.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Linter/ProcessLinter.php @@ -84,7 +84,7 @@ public function __destruct() */ public function __sleep(): array { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + throw new \BadMethodCallException('Cannot serialize '.self::class); } /** @@ -95,7 +95,7 @@ public function __sleep(): array */ public function __wakeup(): void { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + throw new \BadMethodCallException('Cannot unserialize '.self::class); } public function isAsync(): bool diff --git a/vendor/friendsofphp/php-cs-fixer/src/Preg.php b/vendor/friendsofphp/php-cs-fixer/src/Preg.php index 1dadb476..7b040d36 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Preg.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Preg.php @@ -25,8 +25,19 @@ final class Preg { /** - * @param null|string[] $matches - * @param int-mask<0, 256, 512> $flags + * @param array $matches + * @param int-mask $flags + * + * @param-out ($flags is PREG_OFFSET_CAPTURE + * ? array + * : ($flags is PREG_UNMATCHED_AS_NULL + * ? array + * : ($flags is int-mask&768 + * ? array + * : array + * ) + * ) + * ) $matches * * @throws PregException */ @@ -42,11 +53,35 @@ public static function match(string $pattern, string $subject, ?array &$matches return 1 === $result; } - throw self::newPregException(preg_last_error(), __METHOD__, (array) $pattern); + throw self::newPregException(preg_last_error(), preg_last_error_msg(), __METHOD__, $pattern); } /** - * @param null|string[] $matches + * @param array $matches + * @param int-mask $flags + * + * @param-out ($flags is PREG_PATTERN_ORDER + * ? array> + * : ($flags is PREG_SET_ORDER + * ? list> + * : ($flags is int-mask&(256|257) + * ? array> + * : ($flags is int-mask&258 + * ? list> + * : ($flags is int-mask&(512|513) + * ? array> + * : ($flags is int-mask&514 + * ? list> + * : ($flags is int-mask&770 + * ? list> + * : array + * ) + * ) + * ) + * ) + * ) + * ) + * ) $matches * * @throws PregException */ @@ -62,11 +97,13 @@ public static function matchAll(string $pattern, string $subject, ?array &$match return $result; } - throw self::newPregException(preg_last_error(), __METHOD__, (array) $pattern); + throw self::newPregException(preg_last_error(), preg_last_error_msg(), __METHOD__, $pattern); } /** - * @param string|string[] $subject + * @param array|string $subject + * + * @param-out int $count * * @throws PregException */ @@ -82,10 +119,12 @@ public static function replace(string $pattern, string $replacement, $subject, i return $result; } - throw self::newPregException(preg_last_error(), __METHOD__, (array) $pattern); + throw self::newPregException(preg_last_error(), preg_last_error_msg(), __METHOD__, $pattern); } /** + * @param-out int $count + * * @throws PregException */ public static function replaceCallback(string $pattern, callable $callback, string $subject, int $limit = -1, ?int &$count = null): string @@ -100,11 +139,11 @@ public static function replaceCallback(string $pattern, callable $callback, stri return $result; } - throw self::newPregException(preg_last_error(), __METHOD__, (array) $pattern); + throw self::newPregException(preg_last_error(), preg_last_error_msg(), __METHOD__, $pattern); } /** - * @return string[] + * @return list * * @throws PregException */ @@ -120,34 +159,16 @@ public static function split(string $pattern, string $subject, int $limit = -1, return $result; } - throw self::newPregException(preg_last_error(), __METHOD__, (array) $pattern); + throw self::newPregException(preg_last_error(), preg_last_error_msg(), __METHOD__, $pattern); } - /** - * @param string|string[] $pattern - * - * @return string|string[] - */ - private static function addUtf8Modifier($pattern) + private static function addUtf8Modifier(string $pattern): string { - if (\is_array($pattern)) { - return array_map(__METHOD__, $pattern); - } - return $pattern.'u'; } - /** - * @param string|string[] $pattern - * - * @return string|string[] - */ - private static function removeUtf8Modifier($pattern) + private static function removeUtf8Modifier(string $pattern): string { - if (\is_array($pattern)) { - return array_map(__METHOD__, $pattern); - } - if ('' === $pattern) { return ''; } @@ -160,42 +181,35 @@ private static function removeUtf8Modifier($pattern) } /** - * Create PregException. - * - * Create the generic PregException message and if possible due to finding - * an invalid pattern, tell more about such kind of error in the message. - * - * @param string[] $patterns + * Create the generic PregException message and tell more about such kind of error in the message. */ - private static function newPregException(int $error, string $method, array $patterns): PregException + private static function newPregException(int $error, string $errorMsg, string $method, string $pattern): PregException { - foreach ($patterns as $pattern) { - $last = error_get_last(); - $result = @preg_match($pattern, ''); - - if (false !== $result) { - continue; - } - - $code = preg_last_error(); - $next = error_get_last(); - - if ($last !== $next) { - $message = sprintf( - '(code: %d) %s', - $code, - preg_replace('~preg_[a-z_]+[()]{2}: ~', '', $next['message']) - ); - } else { - $message = sprintf('(code: %d)', $code); - } - - return new PregException( - sprintf('%s(): Invalid PCRE pattern "%s": %s (version: %s)', $method, $pattern, $message, PCRE_VERSION), - $code - ); + $result = null; + $errorMessage = null; + + try { + $result = ExecutorWithoutErrorHandler::execute(static fn () => preg_match($pattern, '')); + } catch (ExecutorWithoutErrorHandlerException $e) { + $result = false; + $errorMessage = $e->getMessage(); + } + + if (false !== $result) { + return new PregException(sprintf('Unknown error occurred when calling %s: %s.', $method, $errorMsg), $error); } - return new PregException(sprintf('Error occurred when calling %s.', $method), $error); + $code = preg_last_error(); + + $message = sprintf( + '(code: %d) %s', + $code, + preg_replace('~preg_[a-z_]+[()]{2}: ~', '', $errorMessage) + ); + + return new PregException( + sprintf('%s(): Invalid PCRE pattern "%s": %s (version: %s)', $method, $pattern, $message, PCRE_VERSION), + $code + ); } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/DeprecatedRuleSetDescriptionInterface.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/DeprecatedRuleSetDescriptionInterface.php new file mode 100644 index 00000000..ae52441d --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/DeprecatedRuleSetDescriptionInterface.php @@ -0,0 +1,28 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\RuleSet; + +/** + * @author Greg Korba + */ +interface DeprecatedRuleSetDescriptionInterface extends RuleSetDescriptionInterface +{ + /** + * Returns names of rule sets to use instead, if any. + * + * @return list + */ + public function getSuccessorsNames(): array; +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php index 19f48c09..c860d963 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSet.php @@ -15,6 +15,7 @@ namespace PhpCsFixer\RuleSet; use PhpCsFixer\ConfigurationException\InvalidFixerConfigurationException; +use PhpCsFixer\Utils; /** * Set of rules to be used by fixer. @@ -28,10 +29,10 @@ final class RuleSet implements RuleSetInterface /** * Group of rules generated from input set. * - * The key is name of rule, value is bool if the rule/set should be used. + * The key is name of rule, value is configuration array or true. * The key must not point to any set. * - * @var array|bool> + * @var array|true> */ private array $rules; @@ -107,7 +108,10 @@ private function resolveSet(array $rules): void } // filter out all resolvedRules that are off - $resolvedRules = array_filter($resolvedRules); + $resolvedRules = array_filter( + $resolvedRules, + static fn ($value): bool => false !== $value + ); $this->rules = $resolvedRules; } @@ -122,7 +126,17 @@ private function resolveSet(array $rules): void */ private function resolveSubset(string $setName, bool $setValue): array { - $rules = RuleSets::getSetDefinition($setName)->getRules(); + $ruleSet = RuleSets::getSetDefinition($setName); + + if ($ruleSet instanceof DeprecatedRuleSetDescriptionInterface) { + $messageEnd = [] === $ruleSet->getSuccessorsNames() + ? 'No replacement available' + : sprintf('Use %s instead', Utils::naturalLanguageJoin($ruleSet->getSuccessorsNames())); + + Utils::triggerDeprecation(new \RuntimeException("Rule set \"{$setName}\" is deprecated. {$messageEnd}.")); + } + + $rules = $ruleSet->getRules(); foreach ($rules as $name => $value) { if (str_starts_with($name, '@')) { diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetInterface.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetInterface.php index eb83b6b4..02424825 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetInterface.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSetInterface.php @@ -38,7 +38,7 @@ public function getRuleConfiguration(string $rule): ?array; /** * Get all rules from rules set. * - * @return array|bool> + * @return array|true> */ public function getRules(): array; diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSets.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSets.php index d10ff8c6..54cf2769 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSets.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/RuleSets.php @@ -24,7 +24,7 @@ final class RuleSets { /** - * @var array + * @var array */ private static $setDefinitions; @@ -50,7 +50,7 @@ public static function getSetDefinitions(): array } /** - * @return string[] + * @return list */ public static function getSetDefinitionNames(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0RiskySet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0RiskySet.php index 8794aea6..3e446037 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0RiskySet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0RiskySet.php @@ -21,9 +21,6 @@ * * PER Coding Style v1.0. * - * @TODO 4.0 Remove this class - * - * @deprecated Use `@PER-CS2.0:risky` instead. * @see https://github.com/php-fig/per-coding-style/blob/1.0.0/spec.md */ final class PERCS1x0RiskySet extends AbstractRuleSetDescription @@ -42,10 +39,6 @@ public function getRules(): array public function getDescription(): string { - return <<<'DESC' - **This ruleset is deprecated** in favour of `@PER-CS2.0:risky`. - - Rules that follow `PER Coding Style 1.0 `_. - DESC; + return 'Rules that follow `PER Coding Style 1.0 `_.'; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0Set.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0Set.php index 4081d169..3ad0a6fc 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0Set.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS1x0Set.php @@ -21,9 +21,6 @@ * * PER Coding Style v1.0. * - * @TODO 4.0 Remove this class - * - * @deprecated Use `@PER-CS2.0` instead. * @see https://github.com/php-fig/per-coding-style/blob/1.0.0/spec.md */ final class PERCS1x0Set extends AbstractRuleSetDescription @@ -42,10 +39,6 @@ public function getRules(): array public function getDescription(): string { - return <<<'DESC' - **This ruleset is deprecated** in favour of `@PER-CS2.0`. - - Rules that follow `PER Coding Style 1.0 `_. - DESC; + return 'Rules that follow `PER Coding Style 1.0 `_.'; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS2x0Set.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS2x0Set.php index 5a6df0fe..f336050f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS2x0Set.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERCS2x0Set.php @@ -32,15 +32,28 @@ public function getName(): string public function getRules(): array { - return [ + $rules = [ '@PER-CS1.0' => true, + 'array_indentation' => true, + 'cast_spaces' => true, 'concat_space' => ['spacing' => 'one'], 'function_declaration' => [ 'closure_fn_spacing' => 'none', ], 'method_argument_space' => true, 'single_line_empty_body' => true, + 'trailing_comma_in_multiline' => [ + 'after_heredoc' => true, + 'elements' => ['arguments', 'arrays'], + ], ]; + + if (\PHP_VERSION_ID >= 8_00_00) { + $rules['trailing_comma_in_multiline']['elements'][] = 'match'; + $rules['trailing_comma_in_multiline']['elements'][] = 'parameters'; + } + + return $rules; } public function getDescription(): string diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERRiskySet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERRiskySet.php index e700d4c3..9f156c28 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERRiskySet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERRiskySet.php @@ -15,17 +15,18 @@ namespace PhpCsFixer\RuleSet\Sets; use PhpCsFixer\RuleSet\AbstractRuleSetDescription; +use PhpCsFixer\RuleSet\DeprecatedRuleSetDescriptionInterface; /** * @internal * - * @deprecated Use `@PER-CS2.0:risky` instead. + * @deprecated use `@PER-CS:risky` instead * * @TODO 4.0 remove me * * Last updated to PER Coding Style v2.0. */ -final class PERRiskySet extends AbstractRuleSetDescription +final class PERRiskySet extends AbstractRuleSetDescription implements DeprecatedRuleSetDescriptionInterface { public function getName(): string { @@ -35,12 +36,17 @@ public function getName(): string public function getRules(): array { return [ - '@PER-CS2.0:risky' => true, + '@PER-CS:risky' => true, ]; } public function getDescription(): string { - return 'Alias for the PER-CS risky rules. It is recommended you use ``@PER-CS2.0:risky`` instead.'; + return 'Alias for the newest PER-CS risky rules. It is recommended you use ``@PER-CS2.0:risky`` instead if you want to stick with stable ruleset.'; + } + + public function getSuccessorsNames(): array + { + return ['@PER-CS:risky']; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERSet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERSet.php index 3b2d0b80..81de37de 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERSet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PERSet.php @@ -15,27 +15,33 @@ namespace PhpCsFixer\RuleSet\Sets; use PhpCsFixer\RuleSet\AbstractRuleSetDescription; +use PhpCsFixer\RuleSet\DeprecatedRuleSetDescriptionInterface; /** * @internal * - * @deprecated Use `@PER-CS2.0` instead. + * @deprecated use `@PER-CS` instead * * @TODO 4.0 remove me * * Last updated to PER Coding Style v2.0. */ -final class PERSet extends AbstractRuleSetDescription +final class PERSet extends AbstractRuleSetDescription implements DeprecatedRuleSetDescriptionInterface { public function getRules(): array { return [ - '@PER-CS2.0' => true, + '@PER-CS' => true, ]; } public function getDescription(): string { - return 'Alias for the PER-CS rules. It is recommended you use ``@PER-CS2.0`` instead.'; + return 'Alias for the newest PER-CS rules. It is recommended you use ``@PER-CS2.0`` instead if you want to stick with stable ruleset.'; + } + + public function getSuccessorsNames(): array + { + return ['@PER-CS']; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php new file mode 100644 index 00000000..a2bdfbd9 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP83MigrationSet.php @@ -0,0 +1,30 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\RuleSet\Sets; + +use PhpCsFixer\RuleSet\AbstractMigrationSetDescription; + +/** + * @internal + */ +final class PHP83MigrationSet extends AbstractMigrationSetDescription +{ + public function getRules(): array + { + return [ + '@PHP82Migration' => true, + ]; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php new file mode 100644 index 00000000..480391bd --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PHP84MigrationSet.php @@ -0,0 +1,31 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\RuleSet\Sets; + +use PhpCsFixer\RuleSet\AbstractMigrationSetDescription; + +/** + * @internal + */ +final class PHP84MigrationSet extends AbstractMigrationSetDescription +{ + public function getRules(): array + { + return [ + '@PHP83Migration' => true, + 'nullable_type_declaration_for_default_null_value' => true, + ]; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PSR12Set.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PSR12Set.php index 322d82cc..47719b10 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PSR12Set.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PSR12Set.php @@ -64,7 +64,9 @@ public function getRules(): array 'single_import_per_statement' => ['group_to_single_imports' => false], 'single_trait_insert_per_statement' => true, 'ternary_operator_spaces' => true, - 'unary_operator_spaces' => true, + 'unary_operator_spaces' => [ + 'only_dec_inc' => true, + ], 'visibility_required' => true, ]; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerRiskySet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerRiskySet.php index b90dcbad..9048d242 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerRiskySet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerRiskySet.php @@ -47,10 +47,10 @@ public function getRules(): array '@all', ], ], - 'no_unreachable_default_argument_value' => true, 'no_unset_on_property' => true, 'php_unit_data_provider_name' => true, 'php_unit_data_provider_return_type' => true, + 'php_unit_data_provider_static' => ['force' => true], 'php_unit_strict' => true, 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], 'static_lambda' => true, diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerSet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerSet.php index f9fa314f..e90a02dd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerSet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/PhpCsFixerSet.php @@ -26,7 +26,6 @@ public function getRules(): array return [ '@PER-CS' => true, '@Symfony' => true, - 'array_indentation' => true, 'blank_line_before_statement' => [ 'statements' => [ 'break', @@ -52,9 +51,11 @@ public function getRules(): array 'combine_consecutive_issets' => true, 'combine_consecutive_unsets' => true, 'empty_loop_body' => true, - 'escape_implicit_backslashes' => true, 'explicit_indirect_variable' => true, 'explicit_string_variable' => true, + 'fully_qualified_strict_types' => [ + 'import_symbols' => true, + ], 'heredoc_to_nowdoc' => true, 'method_argument_space' => [ 'on_multiline' => 'ensure_fully_multiline', @@ -102,7 +103,7 @@ public function getRules(): array ], 'no_useless_else' => true, 'no_useless_return' => true, - 'nullable_type_declaration_for_default_null_value' => false, + 'no_whitespace_before_comma_in_array' => ['after_heredoc' => true], 'ordered_class_elements' => true, 'ordered_types' => true, 'php_unit_internal_class' => true, @@ -116,7 +117,9 @@ public function getRules(): array 'return_assignment' => true, 'self_static_accessor' => true, 'single_line_comment_style' => true, + 'single_line_empty_body' => true, 'single_line_throw' => false, + 'string_implicit_backslashes' => ['single_quoted' => 'ignore'], 'whitespace_after_comma_in_array' => ['ensure_single_space' => true], ]; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonyRiskySet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonyRiskySet.php index bd9221bf..f60d9cac 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonyRiskySet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonyRiskySet.php @@ -55,7 +55,6 @@ public function getRules(): array 'no_homoglyph_names' => true, 'no_php4_constructor' => true, 'no_unneeded_final_method' => true, - 'no_unreachable_default_argument_value' => false, 'no_useless_sprintf' => true, 'non_printable_character' => true, 'ordered_traits' => true, diff --git a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonySet.php b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonySet.php index d2b1f177..1b4f38cd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonySet.php +++ b/vendor/friendsofphp/php-cs-fixer/src/RuleSet/Sets/SymfonySet.php @@ -25,7 +25,7 @@ final class SymfonySet extends AbstractRuleSetDescription public function getRules(): array { return [ - '@PSR12' => true, + '@PER-CS2.0' => true, 'align_multiline_comment' => true, 'array_syntax' => true, 'backtick_to_shell_exec' => true, @@ -39,7 +39,6 @@ public function getRules(): array 'allow_single_line_anonymous_functions' => true, 'allow_single_line_empty_anonymous_classes' => true, ], - 'cast_spaces' => true, 'class_attributes_separation' => [ 'elements' => [ 'method' => 'one', @@ -50,12 +49,13 @@ public function getRules(): array ], 'class_reference_name_casing' => true, 'clean_namespace' => true, - 'concat_space' => true, + 'concat_space' => true, // overrides @PER-CS2.0 'declare_parentheses' => true, 'echo_tag_syntax' => true, 'empty_loop_body' => ['style' => 'braces'], 'empty_loop_condition' => true, 'fully_qualified_strict_types' => true, + 'function_declaration' => true, // overrides @PER-CS2.0 'general_phpdoc_tag_rename' => [ 'replacements' => [ 'inheritDocs' => 'inheritDoc', @@ -73,7 +73,7 @@ public function getRules(): array 'linebreak_after_opening_tag' => true, 'magic_constant_casing' => true, 'magic_method_casing' => true, - 'method_argument_space' => [ + 'method_argument_space' => [ // overrides @PER-CS2.0 'on_multiline' => 'ignore', ], 'native_function_casing' => true, @@ -108,6 +108,7 @@ public function getRules(): array 'no_singleline_whitespace_before_semicolons' => true, 'no_spaces_around_offset' => true, 'no_superfluous_phpdoc_tags' => [ + 'allow_hidden_params' => true, 'remove_inheritdoc' => true, ], 'no_trailing_comma_in_singleline' => true, @@ -134,7 +135,8 @@ public function getRules(): array 'no_useless_nullsafe_operator' => true, 'no_whitespace_before_comma_in_array' => true, 'normalize_index_brace' => true, - 'nullable_type_declaration_for_default_null_value' => ['use_nullable_type_declaration' => false], + 'nullable_type_declaration' => true, + 'nullable_type_declaration_for_default_null_value' => true, 'object_operator_without_whitespace' => true, 'operator_linebreak' => [ 'only_booleans' => true, @@ -147,6 +149,10 @@ public function getRules(): array ], 'sort_algorithm' => 'alpha', ], + 'ordered_types' => [ + 'null_adjustment' => 'always_last', + 'sort_algorithm' => 'none', + ], 'php_unit_fqcn_annotation' => true, 'php_unit_method_casing' => true, 'phpdoc_align' => true, @@ -198,6 +204,7 @@ public function getRules(): array 'hash', ], ], + 'single_line_empty_body' => false, // overrides @PER-CS2.0 'single_line_throw' => true, 'single_quote' => true, 'single_space_around_construct' => true, @@ -206,11 +213,15 @@ public function getRules(): array ], 'standardize_increment' => true, 'standardize_not_equals' => true, + 'statement_indentation' => [ + 'stick_comment_to_next_continuous_control_statement' => true, + ], 'switch_continue_to_break' => true, 'trailing_comma_in_multiline' => true, 'trim_array_spaces' => true, 'type_declaration_spaces' => true, 'types_spaces' => true, + 'unary_operator_spaces' => true, 'whitespace_after_comma_in_array' => true, 'yoda_style' => true, ]; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Runner/FileLintingIterator.php b/vendor/friendsofphp/php-cs-fixer/src/Runner/FileLintingIterator.php index 09f5913e..09cec8da 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Runner/FileLintingIterator.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Runner/FileLintingIterator.php @@ -27,7 +27,7 @@ final class FileLintingIterator extends \IteratorIterator { /** - * @var LintingResultInterface + * @var null|LintingResultInterface */ private $currentResult; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Runner/Runner.php b/vendor/friendsofphp/php-cs-fixer/src/Runner/Runner.php index 7a3bc822..89a65d0f 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Runner/Runner.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Runner/Runner.php @@ -154,8 +154,8 @@ private function fixFile(\SplFileInfo $file, LintingResultInterface $lintingResu $tokens = Tokens::fromCode($old); $oldHash = $tokens->getCodeHash(); - $newHash = $oldHash; $new = $old; + $newHash = $oldHash; $appliedFixers = []; @@ -266,7 +266,7 @@ private function fixFile(\SplFileInfo $file, LintingResultInterface $lintingResu } } - $this->cacheManager->setFile($name, $new); + $this->cacheManager->setFileHash($name, $newHash); $this->dispatchEvent( FixerFileProcessedEvent::NAME, diff --git a/vendor/friendsofphp/php-cs-fixer/src/StdinFileInfo.php b/vendor/friendsofphp/php-cs-fixer/src/StdinFileInfo.php index 7ce19091..2fba503e 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/StdinFileInfo.php +++ b/vendor/friendsofphp/php-cs-fixer/src/StdinFileInfo.php @@ -58,7 +58,7 @@ public function getExtension(): string return '.php'; } - public function getFileInfo($className = null): \SplFileInfo + public function getFileInfo($class = null): \SplFileInfo { throw new \BadMethodCallException(sprintf('Method "%s" is not implemented.', __METHOD__)); } @@ -105,7 +105,7 @@ public function getPath(): string return ''; } - public function getPathInfo($className = null): \SplFileInfo + public function getPathInfo($class = null): \SplFileInfo { throw new \BadMethodCallException(sprintf('Method "%s" is not implemented.', __METHOD__)); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AttributeAnalysis.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AttributeAnalysis.php new file mode 100644 index 00000000..c817a6ff --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/AttributeAnalysis.php @@ -0,0 +1,73 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Tokenizer\Analyzer\Analysis; + +/** + * @internal + * + * @phpstan-type _AttributeItems list + */ +final class AttributeAnalysis +{ + private int $startIndex; + private int $endIndex; + private int $openingBracketIndex; + private int $closingBracketIndex; + + /** + * @var _AttributeItems + */ + private array $attributes; + + /** + * @param _AttributeItems $attributes + */ + public function __construct(int $startIndex, int $endIndex, int $openingBracketIndex, int $closingBracketIndex, array $attributes) + { + $this->startIndex = $startIndex; + $this->endIndex = $endIndex; + $this->openingBracketIndex = $openingBracketIndex; + $this->closingBracketIndex = $closingBracketIndex; + $this->attributes = $attributes; + } + + public function getStartIndex(): int + { + return $this->startIndex; + } + + public function getEndIndex(): int + { + return $this->endIndex; + } + + public function getOpeningBracketIndex(): int + { + return $this->openingBracketIndex; + } + + public function getClosingBracketIndex(): int + { + return $this->closingBracketIndex; + } + + /** + * @return _AttributeItems + */ + public function getAttributes(): array + { + return $this->attributes; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DataProviderAnalysis.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DataProviderAnalysis.php index 75490d76..8e3b15fe 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DataProviderAnalysis.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/DataProviderAnalysis.php @@ -14,20 +14,30 @@ namespace PhpCsFixer\Tokenizer\Analyzer\Analysis; +use PhpCsFixer\Console\Application; +use PhpCsFixer\Utils; + final class DataProviderAnalysis { private string $name; private int $nameIndex; - /** @var array */ + /** @var list */ private array $usageIndices; /** - * @param array $usageIndices + * @param list $usageIndices */ public function __construct(string $name, int $nameIndex, array $usageIndices) { + if (!array_is_list($usageIndices)) { + Utils::triggerDeprecation(new \InvalidArgumentException(sprintf( + 'Parameter "usageIndices" should be a list. This will be enforced in version %d.0.', + Application::getMajorVersion() + 1 + ))); + } + $this->name = $name; $this->nameIndex = $nameIndex; $this->usageIndices = $usageIndices; @@ -44,7 +54,7 @@ public function getNameIndex(): int } /** - * @return array + * @return list */ public function getUsageIndices(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/NamespaceUseAnalysis.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/NamespaceUseAnalysis.php index 59127b2f..c1586fbd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/NamespaceUseAnalysis.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/NamespaceUseAnalysis.php @@ -15,6 +15,9 @@ namespace PhpCsFixer\Tokenizer\Analyzer\Analysis; /** + * @author VeeWee + * @author Greg Korba + * * @internal */ final class NamespaceUseAnalysis implements StartEndTokenAwareAnalysis @@ -33,6 +36,11 @@ final class NamespaceUseAnalysis implements StartEndTokenAwareAnalysis */ private string $shortName; + /** + * Is the use statement part of multi-use (`use A, B, C;`, `use A\{B, C};`)? + */ + private bool $isInMulti; + /** * Is the use statement being aliased? */ @@ -48,19 +56,48 @@ final class NamespaceUseAnalysis implements StartEndTokenAwareAnalysis */ private int $endIndex; + /** + * The start index of the single import in the multi-use statement. + */ + private ?int $chunkStartIndex; + + /** + * The end index of the single import in the multi-use statement. + */ + private ?int $chunkEndIndex; + /** * The type of import: class, function or constant. */ private int $type; - public function __construct(string $fullName, string $shortName, bool $isAliased, int $startIndex, int $endIndex, int $type) - { + /** + * @param self::TYPE_* $type + */ + public function __construct( + int $type, + string $fullName, + string $shortName, + bool $isAliased, + bool $isInMulti, + int $startIndex, + int $endIndex, + ?int $chunkStartIndex = null, + ?int $chunkEndIndex = null + ) { + if (true === $isInMulti && (null === $chunkStartIndex || null === $chunkEndIndex)) { + throw new \LogicException('Chunk start and end index must be set when the import is part of a multi-use statement.'); + } + + $this->type = $type; $this->fullName = $fullName; $this->shortName = $shortName; $this->isAliased = $isAliased; + $this->isInMulti = $isInMulti; $this->startIndex = $startIndex; $this->endIndex = $endIndex; - $this->type = $type; + $this->chunkStartIndex = $chunkStartIndex; + $this->chunkEndIndex = $chunkEndIndex; } public function getFullName(): string @@ -78,6 +115,11 @@ public function isAliased(): bool return $this->isAliased; } + public function isInMulti(): bool + { + return $this->isInMulti; + } + public function getStartIndex(): int { return $this->startIndex; @@ -88,6 +130,16 @@ public function getEndIndex(): int return $this->endIndex; } + public function getChunkStartIndex(): ?int + { + return $this->chunkStartIndex; + } + + public function getChunkEndIndex(): ?int + { + return $this->chunkEndIndex; + } + public function getType(): int { return $this->type; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/TypeAnalysis.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/TypeAnalysis.php index a332b244..9709056a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/TypeAnalysis.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/Analysis/TypeAnalysis.php @@ -57,15 +57,14 @@ final class TypeAnalysis implements StartEndTokenAwareAnalysis private int $endIndex; - private bool $nullable; + private bool $nullable = false; /** * @param ($startIndex is null ? null : int) $endIndex */ - public function __construct(string $name, int $startIndex = null, int $endIndex = null) + public function __construct(string $name, ?int $startIndex = null, ?int $endIndex = null) { $this->name = $name; - $this->nullable = false; if (str_starts_with($name, '?')) { $this->name = substr($name, 1); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/AttributeAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/AttributeAnalyzer.php index c67b76bc..615fe3b5 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/AttributeAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/AttributeAnalyzer.php @@ -14,11 +14,15 @@ namespace PhpCsFixer\Tokenizer\Analyzer; +use PhpCsFixer\Preg; +use PhpCsFixer\Tokenizer\Analyzer\Analysis\AttributeAnalysis; use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Tokens; /** * @internal + * + * @phpstan-import-type _AttributeItems from AttributeAnalysis */ final class AttributeAnalyzer { @@ -67,4 +71,109 @@ public static function isAttribute(Tokens $tokens, int $index): bool return 0 === $count; } + + /** + * Find all consecutive elements that start with #[ and end with ] and the attributes inside. + * + * @return list + */ + public static function collect(Tokens $tokens, int $index): array + { + if (!$tokens[$index]->isGivenKind(T_ATTRIBUTE)) { + throw new \InvalidArgumentException('Given index must point to an attribute.'); + } + + // Rewind to first attribute in group + while ($tokens[$prevIndex = $tokens->getPrevMeaningfulToken($index)]->isGivenKind(CT::T_ATTRIBUTE_CLOSE)) { + $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_ATTRIBUTE, $prevIndex); + } + + /** @var list $elements */ + $elements = []; + + $openingIndex = $index; + do { + $elements[] = $element = self::collectOne($tokens, $openingIndex); + $openingIndex = $tokens->getNextMeaningfulToken($element->getEndIndex()); + } while ($tokens[$openingIndex]->isGivenKind(T_ATTRIBUTE)); + + return $elements; + } + + /** + * Find one element that starts with #[ and ends with ] and the attributes inside. + */ + public static function collectOne(Tokens $tokens, int $index): AttributeAnalysis + { + if (!$tokens[$index]->isGivenKind(T_ATTRIBUTE)) { + throw new \InvalidArgumentException('Given index must point to an attribute.'); + } + + $startIndex = $index; + if ($tokens[$prevIndex = $tokens->getPrevMeaningfulToken($index)]->isGivenKind(CT::T_ATTRIBUTE_CLOSE)) { + // Include comments/PHPDoc if they are present + $startIndex = $tokens->getNextNonWhitespace($prevIndex); + } + + $closingIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ATTRIBUTE, $index); + $endIndex = $tokens->getNextNonWhitespace($closingIndex); + + return new AttributeAnalysis( + $startIndex, + $endIndex - 1, + $index, + $closingIndex, + self::collectAttributes($tokens, $index, $closingIndex), + ); + } + + /** + * @return _AttributeItems + */ + private static function collectAttributes(Tokens $tokens, int $index, int $closingIndex): array + { + /** @var _AttributeItems $elements */ + $elements = []; + + do { + $attributeStartIndex = $index + 1; + + $nameStartIndex = $tokens->getNextTokenOfKind($index, [[T_STRING], [T_NS_SEPARATOR]]); + $index = $tokens->getNextTokenOfKind($attributeStartIndex, ['(', ',', [CT::T_ATTRIBUTE_CLOSE]]); + $attributeName = $tokens->generatePartialCode($nameStartIndex, $tokens->getPrevMeaningfulToken($index)); + + // Find closing parentheses, we need to do this in case there's a comma inside the parentheses + if ($tokens[$index]->equals('(')) { + $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); + $index = $tokens->getNextTokenOfKind($index, [',', [CT::T_ATTRIBUTE_CLOSE]]); + } + + $elements[] = [ + 'start' => $attributeStartIndex, + 'end' => $index - 1, + 'name' => $attributeName, + ]; + + $nextIndex = $index; + + // In case there's a comma right before T_ATTRIBUTE_CLOSE + if ($nextIndex < $closingIndex) { + $nextIndex = $tokens->getNextMeaningfulToken($index); + } + } while ($nextIndex < $closingIndex); + + // End last element at newline if it exists and there's no trailing comma + --$index; + while ($tokens[$index]->isWhitespace()) { + if (Preg::match('/\R/', $tokens[$index]->getContent())) { + $lastElementKey = array_key_last($elements); + $elements[$lastElementKey]['end'] = $index - 1; + + break; + } + --$index; + } + + return $elements; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/BlocksAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/BlocksAnalyzer.php index 492d7049..9522e4cd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/BlocksAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/BlocksAnalyzer.php @@ -24,18 +24,14 @@ */ final class BlocksAnalyzer { - public function isBlock(Tokens $tokens, ?int $openIndex, ?int $closeIndex): bool + public function isBlock(Tokens $tokens, int $openIndex, int $closeIndex): bool { - if (null === $openIndex || null === $closeIndex) { - return false; - } - if (!$tokens->offsetExists($openIndex)) { - return false; + throw new \InvalidArgumentException(sprintf('Tokex index %d for potential block opening does not exist.', $openIndex)); } if (!$tokens->offsetExists($closeIndex)) { - return false; + throw new \InvalidArgumentException(sprintf('Token index %d for potential block closure does not exist.', $closeIndex)); } $blockType = $this->getBlockType($tokens[$openIndex]); diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/CommentsAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/CommentsAnalyzer.php index d0d87ef2..c2822c60 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/CommentsAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/CommentsAnalyzer.php @@ -73,18 +73,7 @@ public function isBeforeStructuralElement(Tokens $tokens, int $index): bool throw new \InvalidArgumentException('Given index must point to a comment.'); } - $nextIndex = $index; - do { - $nextIndex = $tokens->getNextMeaningfulToken($nextIndex); - - // @TODO: drop condition when PHP 8.0+ is required - if (\defined('T_ATTRIBUTE')) { - while (null !== $nextIndex && $tokens[$nextIndex]->isGivenKind(T_ATTRIBUTE)) { - $nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ATTRIBUTE, $nextIndex); - $nextIndex = $tokens->getNextMeaningfulToken($nextIndex); - } - } - } while (null !== $nextIndex && $tokens[$nextIndex]->equals('(')); + $nextIndex = $this->getNextTokenIndex($tokens, $index); if (null === $nextIndex || $tokens[$nextIndex]->equals('}')) { return false; @@ -102,7 +91,7 @@ public function isBeforeStructuralElement(Tokens $tokens, int $index): bool return true; } - if ($this->isValidLanguageConstruct($tokens, $token, $nextIndex)) { + if ($this->isValidVariableAssignment($tokens, $token, $nextIndex)) { return true; } @@ -113,12 +102,30 @@ public function isBeforeStructuralElement(Tokens $tokens, int $index): bool return false; } + /** + * Check if comment at given index precedes return statement. + */ + public function isBeforeReturn(Tokens $tokens, int $index): bool + { + if (!$tokens[$index]->isGivenKind([T_COMMENT, T_DOC_COMMENT])) { + throw new \InvalidArgumentException('Given index must point to a comment.'); + } + + $nextIndex = $this->getNextTokenIndex($tokens, $index); + + if (null === $nextIndex || $tokens[$nextIndex]->equals('}')) { + return false; + } + + return $tokens[$nextIndex]->isGivenKind(T_RETURN); + } + /** * Return array of indices that are part of a comment started at given index. * * @param int $index T_COMMENT index * - * @return list + * @return non-empty-list */ public function getCommentBlockIndices(Tokens $tokens, int $index): array { @@ -251,7 +258,7 @@ private function isValidControl(Tokens $tokens, Token $docsToken, int $controlIn * @param Token $docsToken docs Token * @param int $languageConstructIndex index of variable Token */ - private function isValidLanguageConstruct(Tokens $tokens, Token $docsToken, int $languageConstructIndex): bool + private function isValidVariableAssignment(Tokens $tokens, Token $docsToken, int $languageConstructIndex): bool { static $languageStructures = [ T_LIST, @@ -321,4 +328,23 @@ private function getLineBreakCount(Tokens $tokens, int $whiteStart, int $whiteEn return $lineCount; } + + private function getNextTokenIndex(Tokens $tokens, int $startIndex): ?int + { + $nextIndex = $startIndex; + + do { + $nextIndex = $tokens->getNextMeaningfulToken($nextIndex); + + // @TODO: drop condition when PHP 8.0+ is required + if (\defined('T_ATTRIBUTE')) { + while (null !== $nextIndex && $tokens[$nextIndex]->isGivenKind(T_ATTRIBUTE)) { + $nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ATTRIBUTE, $nextIndex); + $nextIndex = $tokens->getNextMeaningfulToken($nextIndex); + } + } + } while (null !== $nextIndex && $tokens[$nextIndex]->equals('(')); + + return $nextIndex; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/DataProviderAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/DataProviderAnalyzer.php index 8d74d7de..78040f3a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/DataProviderAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/DataProviderAnalyzer.php @@ -26,11 +26,11 @@ */ final class DataProviderAnalyzer { - private const REGEX_CLASS = '(?:\\\\?+'.TypeExpression::REGEX_IDENTIFIER + private const REGEX_CLASS = '(?:\\\?+'.TypeExpression::REGEX_IDENTIFIER .'(\\\\'.TypeExpression::REGEX_IDENTIFIER.')*+)'; /** - * @return array + * @return list */ public function getDataProviders(Tokens $tokens, int $startIndex, int $endIndex): array { @@ -50,10 +50,7 @@ public function getDataProviders(Tokens $tokens, int $startIndex, int $endIndex) Preg::matchAll('/@dataProvider\h+(('.self::REGEX_CLASS.'::)?'.TypeExpression::REGEX_IDENTIFIER.')/', $tokens[$docCommentIndex]->getContent(), $matches); - /** @var array $matches */ - $matches = $matches[1]; - - foreach ($matches as $dataProviderName) { + foreach ($matches[1] as $dataProviderName) { $dataProviders[$dataProviderName][] = $docCommentIndex; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FunctionsAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FunctionsAnalyzer.php index 51b2ac03..bcdbe15d 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FunctionsAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/FunctionsAnalyzer.php @@ -184,7 +184,7 @@ public function getFunctionReturnType(Tokens $tokens, int $methodIndex): ?TypeAn public function isTheSameClassCall(Tokens $tokens, int $index): bool { if (!$tokens->offsetExists($index)) { - return false; + throw new \InvalidArgumentException(sprintf('Token index %d does not exist.', $index)); } $operatorIndex = $tokens->getPrevMeaningfulToken($index); @@ -203,7 +203,11 @@ public function isTheSameClassCall(Tokens $tokens, int $index): bool return false; } - return $tokens[$referenceIndex]->equalsAny([[T_VARIABLE, '$this'], [T_STRING, 'self'], [T_STATIC, 'static']], false); + if (!$tokens[$referenceIndex]->equalsAny([[T_VARIABLE, '$this'], [T_STRING, 'self'], [T_STATIC, 'static']], false)) { + return false; + } + + return $tokens[$tokens->getNextMeaningfulToken($index)]->equals('('); } private function buildFunctionsAnalysis(Tokens $tokens): void diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespaceUsesAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespaceUsesAnalyzer.php index 40e9053a..f220ccaf 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespaceUsesAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespaceUsesAnalyzer.php @@ -21,29 +21,34 @@ use PhpCsFixer\Tokenizer\TokensAnalyzer; /** + * @author VeeWee + * @author Greg Korba + * * @internal + * + * @TODO Drop `allowMultiUses` opt-in flag when all fixers are updated and can handle multi-use statements. */ final class NamespaceUsesAnalyzer { /** * @return list */ - public function getDeclarationsFromTokens(Tokens $tokens): array + public function getDeclarationsFromTokens(Tokens $tokens, bool $allowMultiUses = false): array { $tokenAnalyzer = new TokensAnalyzer($tokens); $useIndices = $tokenAnalyzer->getImportUseIndexes(); - return $this->getDeclarations($tokens, $useIndices); + return $this->getDeclarations($tokens, $useIndices, $allowMultiUses); } /** * @return list */ - public function getDeclarationsInNamespace(Tokens $tokens, NamespaceAnalysis $namespace): array + public function getDeclarationsInNamespace(Tokens $tokens, NamespaceAnalysis $namespace, bool $allowMultiUses = false): array { $namespaceUses = []; - foreach ($this->getDeclarationsFromTokens($tokens) as $namespaceUse) { + foreach ($this->getDeclarationsFromTokens($tokens, $allowMultiUses) as $namespaceUse) { if ($namespaceUse->getStartIndex() >= $namespace->getScopeStartIndex() && $namespaceUse->getStartIndex() <= $namespace->getScopeEndIndex()) { $namespaceUses[] = $namespaceUse; } @@ -57,45 +62,124 @@ public function getDeclarationsInNamespace(Tokens $tokens, NamespaceAnalysis $na * * @return list */ - private function getDeclarations(Tokens $tokens, array $useIndices): array + private function getDeclarations(Tokens $tokens, array $useIndices, bool $allowMultiUses = false): array { $uses = []; foreach ($useIndices as $index) { $endIndex = $tokens->getNextTokenOfKind($index, [';', [T_CLOSE_TAG]]); - $analysis = $this->parseDeclaration($tokens, $index, $endIndex); - if (null !== $analysis) { - $uses[] = $analysis; + $declarations = $this->parseDeclarations($index, $endIndex, $tokens); + if (false === $allowMultiUses) { + $declarations = array_filter($declarations, static fn (NamespaceUseAnalysis $declaration) => !$declaration->isInMulti()); + } + + if ([] !== $declarations) { + $uses = array_merge($uses, $declarations); } } return $uses; } - private function parseDeclaration(Tokens $tokens, int $startIndex, int $endIndex): ?NamespaceUseAnalysis + /** + * @return list + */ + private function parseDeclarations(int $startIndex, int $endIndex, Tokens $tokens): array { - $fullName = $shortName = ''; - $aliased = false; + $type = $this->determineImportType($tokens, $startIndex); + $potentialMulti = $tokens->getNextTokenOfKind($startIndex, [',', [CT::T_GROUP_IMPORT_BRACE_OPEN]]); + $multi = null !== $potentialMulti && $potentialMulti < $endIndex; + $index = $tokens->getNextTokenOfKind($startIndex, [[T_STRING], [T_NS_SEPARATOR]]); + $imports = []; + + while (null !== $index && $index <= $endIndex) { + $qualifiedName = $this->getNearestQualifiedName($tokens, $index); + $token = $tokens[$qualifiedName['afterIndex']]; + + if ($token->isGivenKind(CT::T_GROUP_IMPORT_BRACE_OPEN)) { + $groupStart = $groupIndex = $qualifiedName['afterIndex']; + $groupEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_GROUP_IMPORT_BRACE, $groupStart); + + while ($groupIndex < $groupEnd) { + $chunkStart = $tokens->getNextMeaningfulToken($groupIndex); + + // Finish parsing on trailing comma (no more chunks there) + if ($tokens[$chunkStart]->isGivenKind(CT::T_GROUP_IMPORT_BRACE_CLOSE)) { + break; + } + + $groupQualifiedName = $this->getNearestQualifiedName($tokens, $chunkStart); + $imports[] = new NamespaceUseAnalysis( + $type, + $qualifiedName['fullName'].$groupQualifiedName['fullName'], + $groupQualifiedName['shortName'], + $groupQualifiedName['aliased'], + true, + $startIndex, + $endIndex, + $chunkStart, + $tokens->getPrevMeaningfulToken($groupQualifiedName['afterIndex']) + ); + + $groupIndex = $groupQualifiedName['afterIndex']; + } - $type = NamespaceUseAnalysis::TYPE_CLASS; - for ($i = $startIndex; $i <= $endIndex; ++$i) { - $token = $tokens[$i]; - if ($token->equals(',') || $token->isGivenKind(CT::T_GROUP_IMPORT_BRACE_CLOSE)) { - // do not touch group use declarations until the logic of this is added (for example: `use some\a\{ClassD};`) - // ignore multiple use statements that should be split into few separate statements (for example: `use BarB, BarC as C;`) - return null; - } + $index = $groupIndex; + } elseif ($token->equalsAny([',', ';', [T_CLOSE_TAG]])) { + $previousToken = $tokens->getPrevMeaningfulToken($qualifiedName['afterIndex']); + + if (!$tokens[$previousToken]->isGivenKind(CT::T_GROUP_IMPORT_BRACE_CLOSE)) { + $imports[] = new NamespaceUseAnalysis( + $type, + $qualifiedName['fullName'], + $qualifiedName['shortName'], + $qualifiedName['aliased'], + $multi, + $startIndex, + $endIndex, + $multi ? $index : null, + $multi ? $previousToken : null + ); + } - if ($token->isGivenKind(CT::T_FUNCTION_IMPORT)) { - $type = NamespaceUseAnalysis::TYPE_FUNCTION; - } elseif ($token->isGivenKind(CT::T_CONST_IMPORT)) { - $type = NamespaceUseAnalysis::TYPE_CONSTANT; + $index = $qualifiedName['afterIndex']; } - if ($token->isWhitespace() || $token->isComment() || $token->isGivenKind(T_USE)) { - continue; - } + $index = $tokens->getNextMeaningfulToken($index); + } + + return $imports; + } + + /** + * @return NamespaceUseAnalysis::TYPE_* + */ + private function determineImportType(Tokens $tokens, int $startIndex): int + { + $potentialType = $tokens[$tokens->getNextMeaningfulToken($startIndex)]; + + if ($potentialType->isGivenKind(CT::T_FUNCTION_IMPORT)) { + return NamespaceUseAnalysis::TYPE_FUNCTION; + } + + if ($potentialType->isGivenKind(CT::T_CONST_IMPORT)) { + return NamespaceUseAnalysis::TYPE_CONSTANT; + } + + return NamespaceUseAnalysis::TYPE_CLASS; + } + + /** + * @return array{fullName: string, shortName: string, aliased: bool, afterIndex: int} + */ + private function getNearestQualifiedName(Tokens $tokens, int $index): array + { + $fullName = $shortName = ''; + $aliased = false; + + while (null !== $index) { + $token = $tokens[$index]; if ($token->isGivenKind(T_STRING)) { $shortName = $token->getContent(); @@ -106,16 +190,24 @@ private function parseDeclaration(Tokens $tokens, int $startIndex, int $endIndex $fullName .= $token->getContent(); } elseif ($token->isGivenKind(T_AS)) { $aliased = true; + } elseif ($token->equalsAny([ + ',', + ';', + [CT::T_GROUP_IMPORT_BRACE_OPEN], + [CT::T_GROUP_IMPORT_BRACE_CLOSE], + [T_CLOSE_TAG], + ])) { + break; } + + $index = $tokens->getNextMeaningfulToken($index); } - return new NamespaceUseAnalysis( - trim($fullName), - $shortName, - $aliased, - $startIndex, - $endIndex, - $type - ); + return [ + 'fullName' => $fullName, + 'shortName' => $shortName, + 'aliased' => $aliased, + 'afterIndex' => $index, + ]; } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespacesAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespacesAnalyzer.php index 3890523a..10aa1a04 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespacesAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/NamespacesAnalyzer.php @@ -64,8 +64,15 @@ public function getDeclarations(Tokens $tokens): array $index = $scopeEndIndex; } - if (0 === \count($namespaces)) { - $namespaces[] = new NamespaceAnalysis('', '', 0, 0, 0, \count($tokens) - 1); + if (0 === \count($namespaces) && $tokens->isTokenKindFound(T_OPEN_TAG)) { + $namespaces[] = new NamespaceAnalysis( + '', + '', + $openTagIndex = $tokens[0]->isGivenKind(T_INLINE_HTML) ? 1 : 0, + $openTagIndex, + $openTagIndex, + \count($tokens) - 1, + ); } return $namespaces; diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/SwitchAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/SwitchAnalyzer.php new file mode 100644 index 00000000..fce1f9e3 --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Analyzer/SwitchAnalyzer.php @@ -0,0 +1,69 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Tokenizer\Analyzer; + +use PhpCsFixer\Tokenizer\Analyzer\Analysis\SwitchAnalysis; +use PhpCsFixer\Tokenizer\Tokens; + +/** + * @internal + */ +final class SwitchAnalyzer +{ + /** @var array> */ + private static array $cache = []; + + public static function belongsToSwitch(Tokens $tokens, int $index): bool + { + if (!$tokens[$index]->equals(':')) { + return false; + } + + $tokensHash = md5(serialize($tokens->toArray())); + + if (!\array_key_exists($tokensHash, self::$cache)) { + self::$cache[$tokensHash] = self::getColonIndicesForSwitch(clone $tokens); + } + + return \in_array($index, self::$cache[$tokensHash], true); + } + + /** + * @return list + */ + private static function getColonIndicesForSwitch(Tokens $tokens): array + { + $colonIndices = []; + + /** @var SwitchAnalysis $analysis */ + foreach (ControlCaseStructuresAnalyzer::findControlStructures($tokens, [T_SWITCH]) as $analysis) { + if ($tokens[$analysis->getOpenIndex()]->equals(':')) { + $colonIndices[] = $analysis->getOpenIndex(); + } + + foreach ($analysis->getCases() as $case) { + $colonIndices[] = $case->getColonIndex(); + } + + $defaultAnalysis = $analysis->getDefaultAnalysis(); + + if (null !== $defaultAnalysis) { + $colonIndices[] = $defaultAnalysis->getColonIndex(); + } + } + + return $colonIndices; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CT.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CT.php index 0b32ef94..6eae7cca 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CT.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CT.php @@ -19,45 +19,45 @@ */ final class CT { - public const T_ARRAY_INDEX_CURLY_BRACE_CLOSE = 10001; - public const T_ARRAY_INDEX_CURLY_BRACE_OPEN = 10002; - public const T_ARRAY_SQUARE_BRACE_CLOSE = 10003; - public const T_ARRAY_SQUARE_BRACE_OPEN = 10004; - public const T_ARRAY_TYPEHINT = 10005; - public const T_BRACE_CLASS_INSTANTIATION_CLOSE = 10006; - public const T_BRACE_CLASS_INSTANTIATION_OPEN = 10007; - public const T_CLASS_CONSTANT = 10008; - public const T_CONST_IMPORT = 10009; - public const T_CURLY_CLOSE = 10010; - public const T_DESTRUCTURING_SQUARE_BRACE_CLOSE = 10011; - public const T_DESTRUCTURING_SQUARE_BRACE_OPEN = 10012; - public const T_DOLLAR_CLOSE_CURLY_BRACES = 10013; - public const T_DYNAMIC_PROP_BRACE_CLOSE = 10014; - public const T_DYNAMIC_PROP_BRACE_OPEN = 10015; - public const T_DYNAMIC_VAR_BRACE_CLOSE = 10016; - public const T_DYNAMIC_VAR_BRACE_OPEN = 10017; - public const T_FUNCTION_IMPORT = 10018; - public const T_GROUP_IMPORT_BRACE_CLOSE = 10019; - public const T_GROUP_IMPORT_BRACE_OPEN = 10020; - public const T_NAMESPACE_OPERATOR = 10021; - public const T_NULLABLE_TYPE = 10022; - public const T_RETURN_REF = 10023; - public const T_TYPE_ALTERNATION = 10024; - public const T_TYPE_COLON = 10025; - public const T_USE_LAMBDA = 10026; - public const T_USE_TRAIT = 10027; - public const T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC = 10028; - public const T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED = 10029; - public const T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE = 10030; - public const T_ATTRIBUTE_CLOSE = 10031; - public const T_NAMED_ARGUMENT_NAME = 10032; - public const T_NAMED_ARGUMENT_COLON = 10033; - public const T_FIRST_CLASS_CALLABLE = 10034; - public const T_TYPE_INTERSECTION = 10035; - public const T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_OPEN = 10036; - public const T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE = 10037; - public const T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN = 10038; - public const T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE = 10039; + public const T_ARRAY_INDEX_CURLY_BRACE_CLOSE = 10_001; + public const T_ARRAY_INDEX_CURLY_BRACE_OPEN = 10_002; + public const T_ARRAY_SQUARE_BRACE_CLOSE = 10_003; + public const T_ARRAY_SQUARE_BRACE_OPEN = 10_004; + public const T_ARRAY_TYPEHINT = 10_005; + public const T_BRACE_CLASS_INSTANTIATION_CLOSE = 10_006; + public const T_BRACE_CLASS_INSTANTIATION_OPEN = 10_007; + public const T_CLASS_CONSTANT = 10_008; + public const T_CONST_IMPORT = 10_009; + public const T_CURLY_CLOSE = 10_010; + public const T_DESTRUCTURING_SQUARE_BRACE_CLOSE = 10_011; + public const T_DESTRUCTURING_SQUARE_BRACE_OPEN = 10_012; + public const T_DOLLAR_CLOSE_CURLY_BRACES = 10_013; + public const T_DYNAMIC_PROP_BRACE_CLOSE = 10_014; + public const T_DYNAMIC_PROP_BRACE_OPEN = 10_015; + public const T_DYNAMIC_VAR_BRACE_CLOSE = 10_016; + public const T_DYNAMIC_VAR_BRACE_OPEN = 10_017; + public const T_FUNCTION_IMPORT = 10_018; + public const T_GROUP_IMPORT_BRACE_CLOSE = 10_019; + public const T_GROUP_IMPORT_BRACE_OPEN = 10_020; + public const T_NAMESPACE_OPERATOR = 10_021; + public const T_NULLABLE_TYPE = 10_022; + public const T_RETURN_REF = 10_023; + public const T_TYPE_ALTERNATION = 10_024; + public const T_TYPE_COLON = 10_025; + public const T_USE_LAMBDA = 10_026; + public const T_USE_TRAIT = 10_027; + public const T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC = 10_028; + public const T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED = 10_029; + public const T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE = 10_030; + public const T_ATTRIBUTE_CLOSE = 10_031; + public const T_NAMED_ARGUMENT_NAME = 10_032; + public const T_NAMED_ARGUMENT_COLON = 10_033; + public const T_FIRST_CLASS_CALLABLE = 10_034; + public const T_TYPE_INTERSECTION = 10_035; + public const T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_OPEN = 10_036; + public const T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE = 10_037; + public const T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN = 10_038; + public const T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE = 10_039; private function __construct() {} @@ -97,7 +97,7 @@ private static function getMapById(): array static $constants; if (null === $constants) { - $reflection = new \ReflectionClass(__CLASS__); + $reflection = new \ReflectionClass(self::class); $constants = array_flip($reflection->getConstants()); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CodeHasher.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CodeHasher.php index ec316615..86a4a68a 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CodeHasher.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/CodeHasher.php @@ -28,6 +28,8 @@ private function __construct() /** * Calculate hash for code. + * + * @return non-empty-string */ public static function calculateCodeHash(string $code): string { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Processor/ImportProcessor.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Processor/ImportProcessor.php new file mode 100644 index 00000000..35fb0f9d --- /dev/null +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Processor/ImportProcessor.php @@ -0,0 +1,101 @@ + + * Dariusz Rumiński + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace PhpCsFixer\Tokenizer\Processor; + +use PhpCsFixer\Tokenizer\CT; +use PhpCsFixer\Tokenizer\Token; +use PhpCsFixer\Tokenizer\Tokens; +use PhpCsFixer\WhitespacesFixerConfig; + +/** + * @author Greg Korba + */ +final class ImportProcessor +{ + private WhitespacesFixerConfig $whitespacesConfig; + + public function __construct(WhitespacesFixerConfig $whitespacesConfig) + { + $this->whitespacesConfig = $whitespacesConfig; + } + + /** + * @param array{ + * const?: array, + * class?: array, + * function?: array + * } $imports + */ + public function insertImports(Tokens $tokens, array $imports, int $atIndex): void + { + $lineEnding = $this->whitespacesConfig->getLineEnding(); + + if (!$tokens[$atIndex]->isWhitespace() || !str_contains($tokens[$atIndex]->getContent(), "\n")) { + $tokens->insertAt($atIndex, new Token([T_WHITESPACE, $lineEnding])); + } + + foreach ($imports as $type => $typeImports) { + sort($typeImports); + + $items = []; + + foreach ($typeImports as $name) { + $items = array_merge($items, [ + new Token([T_WHITESPACE, $lineEnding]), + new Token([T_USE, 'use']), + new Token([T_WHITESPACE, ' ']), + ]); + + if ('const' === $type) { + $items[] = new Token([CT::T_CONST_IMPORT, 'const']); + $items[] = new Token([T_WHITESPACE, ' ']); + } elseif ('function' === $type) { + $items[] = new Token([CT::T_FUNCTION_IMPORT, 'function']); + $items[] = new Token([T_WHITESPACE, ' ']); + } + + $items = array_merge($items, self::tokenizeName($name)); + $items[] = new Token(';'); + } + + $tokens->insertAt($atIndex, $items); + } + } + + /** + * @param class-string $name + * + * @return list + */ + public static function tokenizeName(string $name): array + { + $parts = explode('\\', $name); + $newTokens = []; + + if ('' === $parts[0]) { + $newTokens[] = new Token([T_NS_SEPARATOR, '\\']); + array_shift($parts); + } + + foreach ($parts as $part) { + $newTokens[] = new Token([T_STRING, $part]); + $newTokens[] = new Token([T_NS_SEPARATOR, '\\']); + } + + array_pop($newTokens); + + return $newTokens; + } +} diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Token.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Token.php index 1009717c..353f88ff 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Token.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Token.php @@ -14,6 +14,8 @@ namespace PhpCsFixer\Tokenizer; +use PhpCsFixer\Utils; + /** * Representation of single token. * As a token prototype you should understand a single element generated by token_get_all. @@ -209,13 +211,20 @@ public function equalsAny(array $others, bool $caseSensitive = true): bool /** * A helper method used to find out whether a certain input token has to be case-sensitively matched. * - * @param bool|list $caseSensitive global case sensitiveness or an array of booleans, whose keys should match - * the ones used in $sequence. If any is missing, the default case-sensitive - * comparison is used - * @param int $key the key of the token that has to be looked up + * @param array|bool $caseSensitive global case sensitiveness or an array of booleans, whose keys should match + * the ones used in $sequence. If any is missing, the default case-sensitive + * comparison is used + * @param int $key the key of the token that has to be looked up + * + * @deprecated */ public static function isKeyCaseSensitive($caseSensitive, int $key): bool { + Utils::triggerDeprecation(new \InvalidArgumentException(sprintf( + 'Method "%s" is deprecated and will be removed in the next major version.', + __METHOD__ + ))); + if (\is_array($caseSensitive)) { return $caseSensitive[$key] ?? true; } @@ -242,6 +251,8 @@ public function getPrototype() * Get token's content. * * It shall be used only for getting the content of token, not for checking it against excepted value. + * + * @return non-empty-string */ public function getContent(): string { @@ -295,7 +306,7 @@ public static function getNameForId(int $id): ?string /** * Generate array containing all keywords that exists in PHP version in use. * - * @return array + * @return list */ public static function getKeywords(): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Tokens.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Tokens.php index a7e2e9ce..f4c7ff83 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Tokens.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Tokens.php @@ -14,9 +14,11 @@ namespace PhpCsFixer\Tokenizer; +use PhpCsFixer\Console\Application; use PhpCsFixer\Preg; use PhpCsFixer\Tokenizer\Analyzer\Analysis\NamespaceAnalysis; use PhpCsFixer\Tokenizer\Analyzer\NamespacesAnalyzer; +use PhpCsFixer\Utils; /** * Collection of code tokens. @@ -52,7 +54,7 @@ class Tokens extends \SplFixedArray /** * Static class cache. * - * @var array + * @var array */ private static array $cache = []; @@ -72,6 +74,8 @@ class Tokens extends \SplFixedArray /** * A MD5 hash of the code string. + * + * @var ?non-empty-string */ private ?string $codeHash = null; @@ -89,7 +93,7 @@ class Tokens extends \SplFixedArray * was ever seen inside the collection (but may not be part of it any longer). * The key is token kind and the value is always true. * - * @var array + * @var array */ private array $foundTokenKinds = []; @@ -111,7 +115,7 @@ public function __clone() /** * Clear cache - one position or all of them. * - * @param null|string $key position to clear, when null clear all + * @param null|non-empty-string $key position to clear, when null clear all */ public static function clearCache(?string $key = null): void { @@ -127,42 +131,52 @@ public static function clearCache(?string $key = null): void /** * Detect type of block. * - * @param Token $token token - * * @return null|array{type: self::BLOCK_TYPE_*, isStart: bool} */ public static function detectBlockType(Token $token): ?array { - foreach (self::getBlockEdgeDefinitions() as $type => $definition) { - if ($token->equals($definition['start'])) { - return ['type' => $type, 'isStart' => true]; - } - - if ($token->equals($definition['end'])) { - return ['type' => $type, 'isStart' => false]; + static $blockEdgeKinds = null; + + if (null === $blockEdgeKinds) { + $blockEdgeKinds = []; + foreach (self::getBlockEdgeDefinitions() as $type => $definition) { + $blockEdgeKinds[ + \is_string($definition['start']) ? $definition['start'] : $definition['start'][0] + ] = ['type' => $type, 'isStart' => true]; + $blockEdgeKinds[ + \is_string($definition['end']) ? $definition['end'] : $definition['end'][0] + ] = ['type' => $type, 'isStart' => false]; } } - return null; + // inlined extractTokenKind() call on the hot path + /** @var int|non-empty-string */ + $tokenKind = $token->isArray() ? $token->getId() : $token->getContent(); + + return $blockEdgeKinds[$tokenKind] ?? null; } /** * Create token collection from array. * - * @param Token[] $array the array to import - * @param ?bool $saveIndices save the numeric indices used in the original array, default is yes + * @param array $array the array to import + * @param ?bool $saveIndices save the numeric indices used in the original array, default is yes */ public static function fromArray($array, $saveIndices = null): self { $tokens = new self(\count($array)); - if ($saveIndices ?? true) { + if (false !== $saveIndices && !array_is_list($array)) { + Utils::triggerDeprecation(new \InvalidArgumentException(sprintf( + 'Parameter "array" should be a list. This will be enforced in version %d.0.', + Application::getMajorVersion() + 1 + ))); + foreach ($array as $key => $val) { $tokens[$key] = $val; } } else { $index = 0; - foreach ($array as $val) { $tokens[$index++] = $val; } @@ -205,67 +219,70 @@ public static function fromCode(string $code): self } /** - * @return array> + * @return array */ public static function getBlockEdgeDefinitions(): array { - $definitions = [ - self::BLOCK_TYPE_CURLY_BRACE => [ - 'start' => '{', - 'end' => '}', - ], - self::BLOCK_TYPE_PARENTHESIS_BRACE => [ - 'start' => '(', - 'end' => ')', - ], - self::BLOCK_TYPE_INDEX_SQUARE_BRACE => [ - 'start' => '[', - 'end' => ']', - ], - self::BLOCK_TYPE_ARRAY_SQUARE_BRACE => [ - 'start' => [CT::T_ARRAY_SQUARE_BRACE_OPEN, '['], - 'end' => [CT::T_ARRAY_SQUARE_BRACE_CLOSE, ']'], - ], - self::BLOCK_TYPE_DYNAMIC_PROP_BRACE => [ - 'start' => [CT::T_DYNAMIC_PROP_BRACE_OPEN, '{'], - 'end' => [CT::T_DYNAMIC_PROP_BRACE_CLOSE, '}'], - ], - self::BLOCK_TYPE_DYNAMIC_VAR_BRACE => [ - 'start' => [CT::T_DYNAMIC_VAR_BRACE_OPEN, '{'], - 'end' => [CT::T_DYNAMIC_VAR_BRACE_CLOSE, '}'], - ], - self::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE => [ - 'start' => [CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN, '{'], - 'end' => [CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE, '}'], - ], - self::BLOCK_TYPE_GROUP_IMPORT_BRACE => [ - 'start' => [CT::T_GROUP_IMPORT_BRACE_OPEN, '{'], - 'end' => [CT::T_GROUP_IMPORT_BRACE_CLOSE, '}'], - ], - self::BLOCK_TYPE_DESTRUCTURING_SQUARE_BRACE => [ - 'start' => [CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, '['], - 'end' => [CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ']'], - ], - self::BLOCK_TYPE_BRACE_CLASS_INSTANTIATION => [ - 'start' => [CT::T_BRACE_CLASS_INSTANTIATION_OPEN, '('], - 'end' => [CT::T_BRACE_CLASS_INSTANTIATION_CLOSE, ')'], - ], - self::BLOCK_TYPE_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS => [ - 'start' => [CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_OPEN, '('], - 'end' => [CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE, ')'], - ], - self::BLOCK_TYPE_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE => [ - 'start' => [CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN, '{'], - 'end' => [CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE, '}'], - ], - ]; - - // @TODO: drop condition when PHP 8.0+ is required - if (\defined('T_ATTRIBUTE')) { - $definitions[self::BLOCK_TYPE_ATTRIBUTE] = [ - 'start' => [T_ATTRIBUTE, '#['], - 'end' => [CT::T_ATTRIBUTE_CLOSE, ']'], + static $definitions = null; + if (null === $definitions) { + $definitions = [ + self::BLOCK_TYPE_CURLY_BRACE => [ + 'start' => '{', + 'end' => '}', + ], + self::BLOCK_TYPE_PARENTHESIS_BRACE => [ + 'start' => '(', + 'end' => ')', + ], + self::BLOCK_TYPE_INDEX_SQUARE_BRACE => [ + 'start' => '[', + 'end' => ']', + ], + self::BLOCK_TYPE_ARRAY_SQUARE_BRACE => [ + 'start' => [CT::T_ARRAY_SQUARE_BRACE_OPEN, '['], + 'end' => [CT::T_ARRAY_SQUARE_BRACE_CLOSE, ']'], + ], + self::BLOCK_TYPE_DYNAMIC_PROP_BRACE => [ + 'start' => [CT::T_DYNAMIC_PROP_BRACE_OPEN, '{'], + 'end' => [CT::T_DYNAMIC_PROP_BRACE_CLOSE, '}'], + ], + self::BLOCK_TYPE_DYNAMIC_VAR_BRACE => [ + 'start' => [CT::T_DYNAMIC_VAR_BRACE_OPEN, '{'], + 'end' => [CT::T_DYNAMIC_VAR_BRACE_CLOSE, '}'], + ], + self::BLOCK_TYPE_ARRAY_INDEX_CURLY_BRACE => [ + 'start' => [CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN, '{'], + 'end' => [CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE, '}'], + ], + self::BLOCK_TYPE_GROUP_IMPORT_BRACE => [ + 'start' => [CT::T_GROUP_IMPORT_BRACE_OPEN, '{'], + 'end' => [CT::T_GROUP_IMPORT_BRACE_CLOSE, '}'], + ], + self::BLOCK_TYPE_DESTRUCTURING_SQUARE_BRACE => [ + 'start' => [CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN, '['], + 'end' => [CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE, ']'], + ], + self::BLOCK_TYPE_BRACE_CLASS_INSTANTIATION => [ + 'start' => [CT::T_BRACE_CLASS_INSTANTIATION_OPEN, '('], + 'end' => [CT::T_BRACE_CLASS_INSTANTIATION_CLOSE, ')'], + ], + self::BLOCK_TYPE_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS => [ + 'start' => [CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_OPEN, '('], + 'end' => [CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE, ')'], + ], + self::BLOCK_TYPE_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE => [ + 'start' => [CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN, '{'], + 'end' => [CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE, '}'], + ], ]; + + // @TODO: drop condition when PHP 8.0+ is required + if (\defined('T_ATTRIBUTE')) { + $definitions[self::BLOCK_TYPE_ATTRIBUTE] = [ + 'start' => [T_ATTRIBUTE, '#['], + 'end' => [CT::T_ATTRIBUTE_CLOSE, ']'], + ]; + } } return $definitions; @@ -276,9 +293,10 @@ public static function getBlockEdgeDefinitions(): array * * @param int $size */ + #[\ReturnTypeWillChange] public function setSize($size): bool { - if ($this->getSize() !== $size) { + if (\count($this) !== $size) { $this->changed = true; $this->namespaceDeclarations = null; @@ -295,10 +313,25 @@ public function setSize($size): bool */ public function offsetUnset($index): void { - $this->changed = true; - $this->namespaceDeclarations = null; + if (\count($this) - 1 !== $index) { + Utils::triggerDeprecation(new \InvalidArgumentException(sprintf( + 'Tokens should be a list - only the last index can be unset. This will be enforced in version %d.0.', + Application::getMajorVersion() + 1 + ))); + } + if (isset($this[$index])) { + if (isset($this->blockStartCache[$index])) { + unset($this->blockEndCache[$this->blockStartCache[$index]], $this->blockStartCache[$index]); + } + if (isset($this->blockEndCache[$index])) { + unset($this->blockStartCache[$this->blockEndCache[$index]], $this->blockEndCache[$index]); + } + $this->unregisterFoundToken($this[$index]); + + $this->changed = true; + $this->namespaceDeclarations = null; } parent::offsetUnset($index); @@ -314,16 +347,28 @@ public function offsetUnset($index): void */ public function offsetSet($index, $newval): void { - $this->blockStartCache = []; - $this->blockEndCache = []; + if (0 > $index || \count($this) <= $index) { + Utils::triggerDeprecation(new \InvalidArgumentException(sprintf( + 'Tokens should be a list - index must be within the existing range. This will be enforced in version %d.0.', + Application::getMajorVersion() + 1 + ))); + } if (!isset($this[$index]) || !$this[$index]->equals($newval)) { - $this->changed = true; - $this->namespaceDeclarations = null; - if (isset($this[$index])) { + if (isset($this->blockStartCache[$index])) { + unset($this->blockEndCache[$this->blockStartCache[$index]], $this->blockStartCache[$index]); + } + if (isset($this->blockEndCache[$index])) { + unset($this->blockStartCache[$this->blockEndCache[$index]], $this->blockEndCache[$index]); + } + $this->unregisterFoundToken($this[$index]); } + + $this->changed = true; + $this->namespaceDeclarations = null; + $this->registerFoundToken($newval); } @@ -345,7 +390,7 @@ public function clearChanged(): void */ public function clearEmptyTokens(): void { - $limit = $this->count(); + $limit = \count($this); for ($index = 0; $index < $limit; ++$index) { if ($this->isEmptyAt($index)) { @@ -365,7 +410,14 @@ public function clearEmptyTokens(): void } } - // we are moving the tokens, we need to clear the indices Cache + // should already be true + if (!$this->changed) { + // must never happen + throw new \LogicException('Unexpected non-changed collection with _EMPTY_ Tokens. Fix the code!'); + } + + // we are moving the tokens, we need to clear the index-based Cache + $this->namespaceDeclarations = null; $this->blockStartCache = []; $this->blockEndCache = []; @@ -438,7 +490,7 @@ public function ensureWhitespaceAtIndex(int $index, int $indexOffset, string $wh * @param self::BLOCK_TYPE_* $type type of block * @param int $searchIndex index of opening brace * - * @return int index of closing brace + * @return int<0, max> index of closing brace */ public function findBlockEnd(int $type, int $searchIndex): int { @@ -449,7 +501,7 @@ public function findBlockEnd(int $type, int $searchIndex): int * @param self::BLOCK_TYPE_* $type type of block * @param int $searchIndex index of closing brace * - * @return int index of opening brace + * @return int<0, max> index of opening brace */ public function findBlockStart(int $type, int $searchIndex): int { @@ -457,16 +509,16 @@ public function findBlockStart(int $type, int $searchIndex): int } /** - * @param int|list $possibleKind kind or array of kinds - * @param int $start optional offset - * @param null|int $end optional limit + * @param int|non-empty-list $possibleKind kind or array of kinds + * @param int $start optional offset + * @param null|int $end optional limit * - * @return array>|array + * @return ($possibleKind is int ? array, Token> : array, Token>>) */ public function findGivenKind($possibleKind, int $start = 0, ?int $end = null): array { if (null === $end) { - $end = $this->count(); + $end = \count($this); } $elements = []; @@ -561,7 +613,6 @@ public function getNonWhitespaceSibling(int $index, int $direction, ?string $whi { while (true) { $index += $direction; - if (!$this->offsetExists($index)) { return null; } @@ -616,7 +667,6 @@ public function getTokenOfKindSibling(int $index, int $direction, array $tokens while (true) { $index += $direction; - if (!$this->offsetExists($index)) { return null; } @@ -684,7 +734,6 @@ public function getNonEmptySibling(int $index, int $direction): ?int { while (true) { $index += $direction; - if (!$this->offsetExists($index)) { return null; } @@ -718,14 +767,14 @@ public function getPrevMeaningfulToken(int $index): ?int /** * Find a sequence of meaningful tokens and returns the array of their locations. * - * @param list $sequence an array of token (kinds) - * @param int $start start index, defaulting to the start of the file - * @param null|int $end end index, defaulting to the end of the file - * @param array|bool $caseSensitive global case sensitiveness or a list of booleans, whose keys should match - * the ones used in $sequence. If any is missing, the default case-sensitive - * comparison is used + * @param non-empty-list $sequence an array of token (kinds) + * @param int $start start index, defaulting to the start of the file + * @param null|int $end end index, defaulting to the end of the file + * @param array|bool $caseSensitive global case sensitiveness or a list of booleans, whose keys should match + * the ones used in $sequence. If any is missing, the default case-sensitive + * comparison is used * - * @return null|array an array containing the tokens matching the sequence elements, indexed by their position + * @return null|non-empty-array, Token> an array containing the tokens matching the sequence elements, indexed by their position */ public function findSequence(array $sequence, int $start = 0, ?int $end = null, $caseSensitive = true): ?array { @@ -773,10 +822,10 @@ public function findSequence(array $sequence, int $start = 0, ?int $end = null, // remove the first token from the sequence, so we can freely iterate through the sequence after a match to // the first one is found - $key = key($sequence); - $firstCs = Token::isKeyCaseSensitive($caseSensitive, $key); - $firstToken = $sequence[$key]; - unset($sequence[$key]); + $firstKey = array_key_first($sequence); + $firstCs = self::isKeyCaseSensitive($caseSensitive, $firstKey); + $firstToken = $sequence[$firstKey]; + unset($sequence[$firstKey]); // begin searching for the first token in the sequence (start included) $index = $start - 1; @@ -803,7 +852,7 @@ public function findSequence(array $sequence, int $start = 0, ?int $end = null, return null; } - if (!$this[$currIdx]->equals($token, Token::isKeyCaseSensitive($caseSensitive, $key))) { + if (!$this[$currIdx]->equals($token, self::isKeyCaseSensitive($caseSensitive, $key))) { // not a match, restart the outer loop continue 2; } @@ -872,7 +921,7 @@ public function insertSlices(array $slices): void $this->setSize($oldSize + $itemsCount); krsort($slices); - $farthestSliceIndex = key($slices); + $farthestSliceIndex = array_key_first($slices); // We check only the farthest index, if it's within the size of collection, other indices will be valid too. if (!\is_int($farthestSliceIndex) || $farthestSliceIndex > $oldSize) { @@ -892,7 +941,7 @@ public function insertSlices(array $slices): void $sliceCount = \count($slice); for ($i = $previousSliceIndex - 1; $i >= $index; --$i) { - parent::offsetSet($i + $itemsCount, parent::offsetGet($i)); + parent::offsetSet($i + $itemsCount, $this[$i]); } $previousSliceIndex = $index; @@ -1107,19 +1156,12 @@ public function clearRange(int $indexStart, int $indexEnd): void */ public function isMonolithicPhp(): bool { - if (0 === $this->count()) { + if (1 !== ($this->countTokenKind(T_OPEN_TAG) + $this->countTokenKind(T_OPEN_TAG_WITH_ECHO))) { return false; } - if ($this->countTokenKind(T_INLINE_HTML) > 1) { - return false; - } - - if (1 === $this->countTokenKind(T_INLINE_HTML)) { - return Preg::match('/^#!.+$/', $this[0]->getContent()); - } - - return 1 === ($this->countTokenKind(T_OPEN_TAG) + $this->countTokenKind(T_OPEN_TAG_WITH_ECHO)); + return 0 === $this->countTokenKind(T_INLINE_HTML) + || (1 === $this->countTokenKind(T_INLINE_HTML) && Preg::match('/^#!.+$/', $this[0]->getContent())); } /** @@ -1236,7 +1278,7 @@ private function removeWhitespaceSafely(int $index, int $direction, ?string $whi * @param int $searchIndex index of starting brace * @param bool $findEnd if method should find block's end or start * - * @return int index of opposite brace + * @return int<0, max> index of opposite brace */ private function findOppositeBlockEdge(int $type, int $searchIndex, bool $findEnd): int { @@ -1257,7 +1299,7 @@ private function findOppositeBlockEdge(int $type, int $searchIndex, bool $findEn $startEdge = $blockEdgeDefinitions[$type]['start']; $endEdge = $blockEdgeDefinitions[$type]['end']; $startIndex = $searchIndex; - $endIndex = $this->count() - 1; + $endIndex = \count($this) - 1; $indexOffset = 1; if (!$findEnd) { @@ -1307,6 +1349,8 @@ private function findOppositeBlockEdge(int $type, int $searchIndex, bool $findEn /** * Calculate hash for code. + * + * @return non-empty-string */ private static function calculateCodeHash(string $code): string { @@ -1316,7 +1360,7 @@ private static function calculateCodeHash(string $code): string /** * Get cache value for given key. * - * @param string $key item key + * @param non-empty-string $key item key */ private static function getCache(string $key): self { @@ -1330,7 +1374,7 @@ private static function getCache(string $key): self /** * Check if given key exists in cache. * - * @param string $key item key + * @param non-empty-string $key item key */ private static function hasCache(string $key): bool { @@ -1338,8 +1382,8 @@ private static function hasCache(string $key): bool } /** - * @param string $key item key - * @param Tokens $value item value + * @param non-empty-string $key item key + * @param Tokens $value item value */ private static function setCache(string $key, self $value): void { @@ -1351,7 +1395,7 @@ private static function setCache(string $key, self $value): void * * Remove old cache and set new one. * - * @param string $codeHash new code hash + * @param non-empty-string $codeHash new code hash */ private function changeCodeHash(string $codeHash): void { @@ -1371,6 +1415,7 @@ private function changeCodeHash(string $codeHash): void private function registerFoundToken($token): void { // inlined extractTokenKind() call on the hot path + /** @var int|non-empty-string */ $tokenKind = $token instanceof Token ? ($token->isArray() ? $token->getId() : $token->getContent()) : (\is_array($token) ? $token[0] : $token); @@ -1387,6 +1432,7 @@ private function registerFoundToken($token): void private function unregisterFoundToken($token): void { // inlined extractTokenKind() call on the hot path + /** @var int|non-empty-string */ $tokenKind = $token instanceof Token ? ($token->isArray() ? $token->getId() : $token->getContent()) : (\is_array($token) ? $token[0] : $token); @@ -1401,7 +1447,7 @@ private function unregisterFoundToken($token): void /** * @param array{int}|string|Token $token token prototype * - * @return int|string + * @return int|non-empty-string */ private function extractTokenKind($token) { @@ -1419,7 +1465,6 @@ private function getTokenNotOfKind(int $index, int $direction, callable $filter) { while (true) { $index += $direction; - if (!$this->offsetExists($index)) { return null; } @@ -1431,4 +1476,21 @@ private function getTokenNotOfKind(int $index, int $direction, callable $filter) return $index; } } + + /** + * A helper method used to find out whether a certain input token has to be case-sensitively matched. + * + * @param array|bool $caseSensitive global case sensitiveness or an array of booleans, whose keys should match + * the ones used in $sequence. If any is missing, the default case-sensitive + * comparison is used + * @param int $key the key of the token that has to be looked up + */ + private static function isKeyCaseSensitive($caseSensitive, int $key): bool + { + if (\is_array($caseSensitive)) { + return $caseSensitive[$key] ?? true; + } + + return $caseSensitive; + } } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/TokensAnalyzer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/TokensAnalyzer.php index 18ee0407..1fbfce97 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/TokensAnalyzer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/TokensAnalyzer.php @@ -26,6 +26,8 @@ * @author Gregor Harlan * * @internal + * + * @phpstan-type _ClassyElementType 'case'|'const'|'method'|'property'|'trait_import' */ final class TokensAnalyzer { @@ -44,7 +46,7 @@ public function __construct(Tokens $tokens) /** * Get indices of methods and properties in classy code (classes, interfaces and traits). * - * @return array + * @return array */ public function getClassyElements(): array { @@ -381,7 +383,7 @@ public function isConstantInvocation(int $index): bool $prevIndex = $this->tokens->getPrevMeaningfulToken($prevIndex); } - if ($this->tokens[$prevIndex]->isGivenKind([CT::T_CONST_IMPORT, T_EXTENDS, CT::T_FUNCTION_IMPORT, T_IMPLEMENTS, T_INSTANCEOF, T_INSTEADOF, T_NAMESPACE, T_NEW, CT::T_NULLABLE_TYPE, CT::T_TYPE_COLON, T_USE, CT::T_USE_TRAIT])) { + if ($this->tokens[$prevIndex]->isGivenKind([CT::T_CONST_IMPORT, T_EXTENDS, CT::T_FUNCTION_IMPORT, T_IMPLEMENTS, T_INSTANCEOF, T_INSTEADOF, T_NAMESPACE, T_NEW, CT::T_NULLABLE_TYPE, CT::T_TYPE_COLON, T_USE, CT::T_USE_TRAIT, CT::T_TYPE_INTERSECTION, CT::T_TYPE_ALTERNATION, T_CONST, CT::T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE])) { return false; } @@ -552,13 +554,15 @@ public function isUnaryPredecessorOperator(int $index): bool ';', '{', '}', + [T_DOUBLE_ARROW], + [T_FN], [T_FUNCTION], [T_OPEN_TAG], [T_OPEN_TAG_WITH_ECHO], ]; $prevToken = $tokens[$tokens->getPrevTokenOfKind($index, $searchTokens)]; - return $prevToken->isGivenKind(T_FUNCTION); + return $prevToken->isGivenKind([T_FN, T_FUNCTION]); } /** @@ -723,7 +727,7 @@ public function isSuperGlobal(int $index): bool * * @param int $classIndex classy index * - * @return array{int, array} + * @return array{int, array} */ private function findClassyElements(int $classIndex, int $index): array { diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformer/NameQualifiedTransformer.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformer/NameQualifiedTransformer.php index b0521954..ed8353c8 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformer/NameQualifiedTransformer.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformer/NameQualifiedTransformer.php @@ -15,6 +15,7 @@ namespace PhpCsFixer\Tokenizer\Transformer; use PhpCsFixer\Tokenizer\AbstractTransformer; +use PhpCsFixer\Tokenizer\Processor\ImportProcessor; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; @@ -51,38 +52,15 @@ public function getCustomTokens(): array private function transformQualified(Tokens $tokens, Token $token, int $index): void { - $parts = explode('\\', $token->getContent()); - $newTokens = []; - - if ('' === $parts[0]) { - $newTokens[] = new Token([T_NS_SEPARATOR, '\\']); - array_shift($parts); - } - - foreach ($parts as $part) { - $newTokens[] = new Token([T_STRING, $part]); - $newTokens[] = new Token([T_NS_SEPARATOR, '\\']); - } - - array_pop($newTokens); + $newTokens = ImportProcessor::tokenizeName($token->getContent()); $tokens->overrideRange($index, $index, $newTokens); } private function transformRelative(Tokens $tokens, Token $token, int $index): void { - $parts = explode('\\', $token->getContent()); - $newTokens = [ - new Token([T_NAMESPACE, array_shift($parts)]), - new Token([T_NS_SEPARATOR, '\\']), - ]; - - foreach ($parts as $part) { - $newTokens[] = new Token([T_STRING, $part]); - $newTokens[] = new Token([T_NS_SEPARATOR, '\\']); - } - - array_pop($newTokens); + $newTokens = ImportProcessor::tokenizeName($token->getContent()); + $newTokens[0] = new Token([T_NAMESPACE, 'namespace']); $tokens->overrideRange($index, $index, $newTokens); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformers.php b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformers.php index e8745538..e5650659 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformers.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Tokenizer/Transformers.php @@ -101,7 +101,7 @@ private function findBuiltInTransformers(): iterable /** @var SplFileInfo $file */ foreach (Finder::create()->files()->in(__DIR__.'/Transformer') as $file) { $relativeNamespace = $file->getRelativePath(); - $class = __NAMESPACE__.'\\Transformer\\'.('' !== $relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php'); + $class = __NAMESPACE__.'\Transformer\\'.('' !== $relativeNamespace ? $relativeNamespace.'\\' : '').$file->getBasename('.php'); yield new $class(); } diff --git a/vendor/friendsofphp/php-cs-fixer/src/ToolInfo.php b/vendor/friendsofphp/php-cs-fixer/src/ToolInfo.php index cab29e45..fe5bdcea 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/ToolInfo.php +++ b/vendor/friendsofphp/php-cs-fixer/src/ToolInfo.php @@ -98,6 +98,15 @@ public function isInstalledByComposer(): bool return $this->isInstalledByComposer; } + /** + * Determines if the tool is run inside our pre-built Docker image. + * The `/fixer/` path comes from our Dockerfile, tool is installed there and added to global PATH via symlinked binary. + */ + public function isRunInsideDocker(): bool + { + return is_file('/.dockerenv') && str_starts_with(__FILE__, '/fixer/'); + } + public function getPharDownloadUri(string $version): string { return sprintf( diff --git a/vendor/friendsofphp/php-cs-fixer/src/ToolInfoInterface.php b/vendor/friendsofphp/php-cs-fixer/src/ToolInfoInterface.php index 5124292b..bc2a5e0b 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/ToolInfoInterface.php +++ b/vendor/friendsofphp/php-cs-fixer/src/ToolInfoInterface.php @@ -32,5 +32,7 @@ public function isInstalledAsPhar(): bool; public function isInstalledByComposer(): bool; + public function isRunInsideDocker(): bool; + public function getPharDownloadUri(string $version): string; } diff --git a/vendor/friendsofphp/php-cs-fixer/src/Utils.php b/vendor/friendsofphp/php-cs-fixer/src/Utils.php index b89d4e18..071781bd 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/Utils.php +++ b/vendor/friendsofphp/php-cs-fixer/src/Utils.php @@ -43,7 +43,7 @@ private function __construct() */ public static function camelCaseToUnderscore(string $string): string { - return mb_strtolower(Preg::replace('/(? $elements + * @param callable(T): R $getComparedValue a callable that takes a single element and returns the value to compare + * @param callable(R, R): int $compareValues a callable that compares two values + * + * @return list */ public static function stableSort(array $elements, callable $getComparedValue, callable $compareValues): array { @@ -102,9 +105,9 @@ public static function stableSort(array $elements, callable $getComparedValue, c /** * Sort fixers by their priorities. * - * @param FixerInterface[] $fixers + * @param list $fixers * - * @return FixerInterface[] + * @return list */ public static function sortFixers(array $fixers): array { @@ -120,7 +123,7 @@ public static function sortFixers(array $fixers): array /** * Join names in natural language using specified wrapper (double quote by default). * - * @param string[] $names + * @param list $names * * @throws \InvalidArgumentException */ @@ -148,7 +151,7 @@ public static function naturalLanguageJoin(array $names, string $wrapper = '"'): /** * Join names in natural language wrapped in backticks, e.g. `a`, `b` and `c`. * - * @param string[] $names + * @param list $names * * @throws \InvalidArgumentException */ @@ -157,9 +160,17 @@ public static function naturalLanguageJoinWithBackticks(array $names): string return self::naturalLanguageJoin($names, '`'); } + public static function isFutureModeEnabled(): bool + { + return filter_var( + getenv('PHP_CS_FIXER_FUTURE_MODE'), + FILTER_VALIDATE_BOOL + ); + } + public static function triggerDeprecation(\Exception $futureException): void { - if (getenv('PHP_CS_FIXER_FUTURE_MODE')) { + if (self::isFutureModeEnabled()) { throw new \RuntimeException( 'Your are using something deprecated, see previous exception. Aborting execution because `PHP_CS_FIXER_FUTURE_MODE` environment variable is set.', 0, @@ -205,7 +216,7 @@ private static function scalarToString($value): string } /** - * @param array $value + * @param array $value */ private static function arrayToString(array $value): string { diff --git a/vendor/friendsofphp/php-cs-fixer/src/WordMatcher.php b/vendor/friendsofphp/php-cs-fixer/src/WordMatcher.php index 36265a88..1525cf51 100644 --- a/vendor/friendsofphp/php-cs-fixer/src/WordMatcher.php +++ b/vendor/friendsofphp/php-cs-fixer/src/WordMatcher.php @@ -22,12 +22,12 @@ final class WordMatcher { /** - * @var string[] + * @var list */ private array $candidates; /** - * @param string[] $candidates + * @param list $candidates */ public function __construct(array $candidates) {