From 4bcd860b6574fd71553019296965613cbaf95161 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 5 Sep 2021 16:02:10 +0200 Subject: [PATCH] Add more type annotations --- src/Composer/DependencyResolver/Decisions.php | 6 +- .../DependencyResolver/DefaultPolicy.php | 2 + .../DependencyResolver/GenericRule.php | 7 +- .../DependencyResolver/MultiConflictRule.php | 5 +- src/Composer/DependencyResolver/Pool.php | 2 + .../DependencyResolver/PoolBuilder.php | 5 ++ src/Composer/DependencyResolver/Problem.php | 5 +- src/Composer/DependencyResolver/Request.php | 13 +++- src/Composer/DependencyResolver/Rule.php | 38 +++++++---- .../DependencyResolver/Rule2Literals.php | 7 +- src/Composer/DependencyResolver/RuleSet.php | 26 ++++--- .../DependencyResolver/RuleSetGenerator.php | 67 +++++++++++-------- .../DependencyResolver/RuleSetIterator.php | 9 +++ .../DependencyResolver/RuleWatchChain.php | 3 +- .../DependencyResolver/RuleWatchGraph.php | 3 +- .../DependencyResolver/RuleWatchNode.php | 5 +- src/Composer/DependencyResolver/Solver.php | 4 +- .../SolverProblemsException.php | 7 ++ .../DependencyResolver/Transaction.php | 20 +++--- .../Downloader/TransportException.php | 4 ++ src/Composer/Downloader/VcsDownloader.php | 2 +- src/Composer/Downloader/ZipDownloader.php | 3 + src/Composer/Installer/BinaryInstaller.php | 4 ++ src/Composer/Installer/LibraryInstaller.php | 10 ++- src/Composer/Installer/PluginInstaller.php | 4 +- .../RuleSetIteratorTest.php | 7 +- .../Test/DependencyResolver/RuleSetTest.php | 33 ++++----- .../Test/DependencyResolver/RuleTest.php | 24 +++---- .../DependencyResolver/TransactionTest.php | 11 ++- 29 files changed, 217 insertions(+), 119 deletions(-) diff --git a/src/Composer/DependencyResolver/Decisions.php b/src/Composer/DependencyResolver/Decisions.php index e69d1a00d975..799a0a1fa5ad 100644 --- a/src/Composer/DependencyResolver/Decisions.php +++ b/src/Composer/DependencyResolver/Decisions.php @@ -16,17 +16,21 @@ * Stores decisions on installing, removing or keeping packages * * @author Nils Adermann + * @implements \Iterator */ class Decisions implements \Iterator, \Countable { const DECISION_LITERAL = 0; const DECISION_REASON = 1; + /** @var Pool */ protected $pool; + /** @var array */ protected $decisionMap; + /** @var array */ protected $decisionQueue = array(); - public function __construct($pool) + public function __construct(Pool $pool) { $this->pool = $pool; $this->decisionMap = array(); diff --git a/src/Composer/DependencyResolver/DefaultPolicy.php b/src/Composer/DependencyResolver/DefaultPolicy.php index dc8e1773666f..832a009e5c1f 100644 --- a/src/Composer/DependencyResolver/DefaultPolicy.php +++ b/src/Composer/DependencyResolver/DefaultPolicy.php @@ -23,7 +23,9 @@ */ class DefaultPolicy implements PolicyInterface { + /** @var bool */ private $preferStable; + /** @var bool */ private $preferLowest; public function __construct($preferStable = false, $preferLowest = false) diff --git a/src/Composer/DependencyResolver/GenericRule.php b/src/Composer/DependencyResolver/GenericRule.php index 39c4783edb47..61d95275fde1 100644 --- a/src/Composer/DependencyResolver/GenericRule.php +++ b/src/Composer/DependencyResolver/GenericRule.php @@ -21,14 +21,11 @@ */ class GenericRule extends Rule { + /** @var int[] */ protected $literals; /** - * @param array $literals - * @param int|null $reason A RULE_* constant describing the reason for generating this rule - * @param Link|BasePackage|int|null|array $reasonData - * - * @phpstan-param Link|BasePackage|int|null|array{packageName: string, constraint: ConstraintInterface} $reasonData + * @param int[] $literals */ public function __construct(array $literals, $reason, $reasonData) { diff --git a/src/Composer/DependencyResolver/MultiConflictRule.php b/src/Composer/DependencyResolver/MultiConflictRule.php index 262f34504248..16a7bd9e244c 100644 --- a/src/Composer/DependencyResolver/MultiConflictRule.php +++ b/src/Composer/DependencyResolver/MultiConflictRule.php @@ -22,12 +22,11 @@ */ class MultiConflictRule extends Rule { + /** @var int[] */ protected $literals; /** - * @param array $literals - * @param int $reason A RULE_* constant describing the reason for generating this rule - * @param Link|BasePackage $reasonData + * @param int[] $literals */ public function __construct(array $literals, $reason, $reasonData) { diff --git a/src/Composer/DependencyResolver/Pool.php b/src/Composer/DependencyResolver/Pool.php index 5fd5ff607f2e..733b0edf5551 100644 --- a/src/Composer/DependencyResolver/Pool.php +++ b/src/Composer/DependencyResolver/Pool.php @@ -30,7 +30,9 @@ class Pool implements \Countable protected $packages = array(); /** @var array */ protected $packageByName = array(); + /** @var VersionParser */ protected $versionParser; + /** @var array> */ protected $providerCache = array(); /** @var BasePackage[] */ protected $unacceptableFixedOrLockedPackages; diff --git a/src/Composer/DependencyResolver/PoolBuilder.php b/src/Composer/DependencyResolver/PoolBuilder.php index a8a4ecbeeab5..97159a3c8f89 100644 --- a/src/Composer/DependencyResolver/PoolBuilder.php +++ b/src/Composer/DependencyResolver/PoolBuilder.php @@ -94,7 +94,9 @@ class PoolBuilder * @phpstan-var list */ private $unacceptableFixedOrLockedPackages = array(); + /** @var string[] */ private $updateAllowList = array(); + /** @var array */ private $skippedLoad = array(); /** @@ -104,6 +106,8 @@ class PoolBuilder * * Packages get cleared from this list if they get unlocked as in that case * we need to actually load them + * + * @var array */ private $maxExtendedReqs = array(); /** @@ -112,6 +116,7 @@ class PoolBuilder */ private $updateAllowWarned = array(); + /** @var int */ private $indexCounter = 0; /** diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 6a490dd1ddf6..35ce3b045386 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -30,16 +30,17 @@ class Problem { /** * A map containing the id of each rule part of this problem as a key - * @var array + * @var array */ protected $reasonSeen; /** * A set of reasons for the problem, each is a rule or a root require and a rule - * @var array + * @var array> */ protected $reasons = array(); + /** @var int */ protected $section = 0; /** diff --git a/src/Composer/DependencyResolver/Request.php b/src/Composer/DependencyResolver/Request.php index 5167ce63c810..3514bd4c8751 100644 --- a/src/Composer/DependencyResolver/Request.php +++ b/src/Composer/DependencyResolver/Request.php @@ -40,12 +40,19 @@ class Request */ const UPDATE_LISTED_WITH_TRANSITIVE_DEPS = 2; + /** @var ?LockArrayRepository */ protected $lockedRepository; + /** @var array */ protected $requires = array(); + /** @var array */ protected $fixedPackages = array(); + /** @var array */ protected $lockedPackages = array(); + /** @var array */ protected $fixedLockedPackages = array(); + /** @var string[] */ protected $updateAllowList = array(); + /** @var false|self::UPDATE_* */ protected $updateAllowTransitiveDependencies = false; public function __construct(LockArrayRepository $lockedRepository = null) @@ -169,12 +176,12 @@ public function getPresentMap($packageIds = false) if ($this->lockedRepository) { foreach ($this->lockedRepository->getPackages() as $package) { - $presentMap[$packageIds ? $package->id : spl_object_hash($package)] = $package; + $presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package; } } foreach ($this->fixedPackages as $package) { - $presentMap[$packageIds ? $package->id : spl_object_hash($package)] = $package; + $presentMap[$packageIds ? $package->getId() : spl_object_hash($package)] = $package; } return $presentMap; @@ -185,7 +192,7 @@ public function getFixedPackagesMap() $fixedPackagesMap = array(); foreach ($this->fixedPackages as $package) { - $fixedPackagesMap[$package->id] = $package; + $fixedPackagesMap[$package->getId()] = $package; } return $fixedPackagesMap; diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index f1b4a7419bdb..edc486496872 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -19,35 +19,45 @@ use Composer\Repository\PlatformRepository; use Composer\Package\Version\VersionParser; use Composer\Semver\Constraint\Constraint; +use Composer\Semver\Constraint\ConstraintInterface; /** * @author Nils Adermann * @author Ruben Gonzalez + * @phpstan-type ReasonData Link|BasePackage|string|int|array{packageName: string, constraint: ConstraintInterface}|array{package: BasePackage} */ abstract class Rule { - // reason constants - const RULE_ROOT_REQUIRE = 2; - const RULE_FIXED = 3; - const RULE_PACKAGE_CONFLICT = 6; - const RULE_PACKAGE_REQUIRES = 7; - const RULE_PACKAGE_SAME_NAME = 10; - const RULE_LEARNED = 12; - const RULE_PACKAGE_ALIAS = 13; - const RULE_PACKAGE_INVERSE_ALIAS = 14; + // reason constants and // their reason data contents + const RULE_ROOT_REQUIRE = 2; // array{packageName: string, constraint: ConstraintInterface} + const RULE_FIXED = 3; // array{package: BasePackage} + const RULE_PACKAGE_CONFLICT = 6; // Link + const RULE_PACKAGE_REQUIRES = 7; // Link + const RULE_PACKAGE_SAME_NAME = 10; // string (package name) + const RULE_LEARNED = 12; // int (rule id) + const RULE_PACKAGE_ALIAS = 13; // BasePackage + const RULE_PACKAGE_INVERSE_ALIAS = 14; // BasePackage // bitfield defs const BITFIELD_TYPE = 0; const BITFIELD_REASON = 8; const BITFIELD_DISABLED = 16; + /** @var int */ protected $bitfield; + /** @var Request */ protected $request; + /** + * @var Link|BasePackage|ConstraintInterface|string + * @phpstan-var ReasonData + */ protected $reasonData; /** - * @param int $reason A RULE_* constant describing the reason for generating this rule - * @param Link|BasePackage $reasonData + * @param self::RULE_* $reason A RULE_* constant describing the reason for generating this rule + * @param Link|BasePackage|ConstraintInterface|string $reasonData + * + * @phpstan-param ReasonData $reasonData */ public function __construct($reason, $reasonData) { @@ -253,17 +263,19 @@ public function getPrettyString(RepositorySet $repositorySet, Request $request, case self::RULE_PACKAGE_REQUIRES: $sourceLiteral = array_shift($literals); $sourcePackage = $this->deduplicateDefaultBranchAlias($pool->literalToPackage($sourceLiteral)); + /** @var Link */ + $reasonData = $this->reasonData; $requires = array(); foreach ($literals as $literal) { $requires[] = $pool->literalToPackage($literal); } - $text = $this->reasonData->getPrettyString($sourcePackage); + $text = $reasonData->getPrettyString($sourcePackage); if ($requires) { $text .= ' -> satisfiable by ' . $this->formatPackagesUnique($pool, $requires, $isVerbose) . '.'; } else { - $targetName = $this->reasonData->getTarget(); + $targetName = $reasonData->getTarget(); $reason = Problem::getMissingPackageReason($repositorySet, $request, $pool, $isVerbose, $targetName, $this->reasonData->getConstraint()); diff --git a/src/Composer/DependencyResolver/Rule2Literals.php b/src/Composer/DependencyResolver/Rule2Literals.php index 6a3eb7c94fa1..6a4c599ced4a 100644 --- a/src/Composer/DependencyResolver/Rule2Literals.php +++ b/src/Composer/DependencyResolver/Rule2Literals.php @@ -20,14 +20,14 @@ */ class Rule2Literals extends Rule { + /** @var int */ protected $literal1; + /** @var int */ protected $literal2; /** * @param int $literal1 * @param int $literal2 - * @param int $reason A RULE_* constant describing the reason for generating this rule - * @param Link|BasePackage $reasonData */ public function __construct($literal1, $literal2, $reason, $reasonData) { @@ -42,11 +42,13 @@ public function __construct($literal1, $literal2, $reason, $reasonData) } } + /** @return int[] */ public function getLiterals() { return array($this->literal1, $this->literal2); } + /** @return string */ public function getHash() { return $this->literal1.','.$this->literal2; @@ -91,6 +93,7 @@ public function equals(Rule $rule) return true; } + /** @return false */ public function isAssertion() { return false; diff --git a/src/Composer/DependencyResolver/RuleSet.php b/src/Composer/DependencyResolver/RuleSet.php index 0ac2bd762509..ba9aeaee218b 100644 --- a/src/Composer/DependencyResolver/RuleSet.php +++ b/src/Composer/DependencyResolver/RuleSet.php @@ -16,6 +16,7 @@ /** * @author Nils Adermann + * @implements \IteratorAggregate */ class RuleSet implements \IteratorAggregate, \Countable { @@ -27,10 +28,11 @@ class RuleSet implements \IteratorAggregate, \Countable /** * READ-ONLY: Lookup table for rule id to rule object * - * @var Rule[] + * @var array */ - public $ruleById; + public $ruleById = array(); + /** @var array<255|0|1|4, string> */ protected static $types = array( 255 => 'UNKNOWN', self::TYPE_PACKAGE => 'PACKAGE', @@ -38,20 +40,20 @@ class RuleSet implements \IteratorAggregate, \Countable self::TYPE_LEARNED => 'LEARNED', ); + /** @var array */ protected $rules; - protected $nextRuleId; - protected $rulesByHash; + /** @var int */ + protected $nextRuleId = 0; + + /** @var array */ + protected $rulesByHash = array(); public function __construct() { - $this->nextRuleId = 0; - foreach ($this->getTypes() as $type) { $this->rules[$type] = array(); } - - $this->rulesByHash = array(); } public function add(Rule $rule, $type) @@ -109,6 +111,7 @@ public function ruleById($id) return $this->ruleById[$id]; } + /** @return array */ public function getRules() { return $this->rules; @@ -123,6 +126,10 @@ public function getIterator() return new RuleSetIterator($this->getRules()); } + /** + * @param self::TYPE_*|array $types + * @return RuleSetIterator + */ public function getIteratorFor($types) { if (!\is_array($types)) { @@ -130,6 +137,8 @@ public function getIteratorFor($types) } $allRules = $this->getRules(); + + /** @var array $rules */ $rules = array(); foreach ($types as $type) { @@ -154,6 +163,7 @@ public function getIteratorWithout($types) return new RuleSetIterator($rules); } + /** @return array{0: 0, 1: 1, 2: 4} */ public function getTypes() { $types = self::$types; diff --git a/src/Composer/DependencyResolver/RuleSetGenerator.php b/src/Composer/DependencyResolver/RuleSetGenerator.php index d9da5e06229b..245f1fdda2e2 100644 --- a/src/Composer/DependencyResolver/RuleSetGenerator.php +++ b/src/Composer/DependencyResolver/RuleSetGenerator.php @@ -14,25 +14,31 @@ use Composer\Package\BasePackage; use Composer\Package\AliasPackage; +use Composer\Package\PackageInterface; use Composer\Repository\PlatformRepository; /** * @author Nils Adermann + * @phpstan-import-type ReasonData from Rule */ class RuleSetGenerator { + /** @var PolicyInterface */ protected $policy; + /** @var Pool */ protected $pool; + /** @var RuleSet */ protected $rules; - protected $addedMap; - protected $conflictAddedMap; - protected $addedPackagesByNames; - protected $conflictsForName; + /** @var array */ + protected $addedMap = array(); + /** @var array */ + protected $addedPackagesByNames = array(); public function __construct(PolicyInterface $policy, Pool $pool) { $this->policy = $policy; $this->pool = $pool; + $this->rules = new RuleSet; } /** @@ -41,13 +47,15 @@ public function __construct(PolicyInterface $policy, Pool $pool) * This rule is of the form (-A|B|C), where B and C are the providers of * one requirement of the package A. * - * @param BasePackage $package The package with a requirement - * @param array $providers The providers of the requirement - * @param int $reason A RULE_* constant describing the - * reason for generating this rule - * @param mixed $reasonData Any data, e.g. the requirement name, - * that goes with the reason - * @return Rule|null The generated rule or null if tautological + * @param BasePackage $package The package with a requirement + * @param array $providers The providers of the requirement + * @param Rule::RULE_* $reason A RULE_* constant describing the + * reason for generating this rule + * @param mixed $reasonData Any data, e.g. the requirement name, + * that goes with the reason + * @return Rule|null The generated rule or null if tautological + * + * @phpstan-param ReasonData $reasonData */ protected function createRequireRule(BasePackage $package, array $providers, $reason, $reasonData = null) { @@ -71,10 +79,12 @@ protected function createRequireRule(BasePackage $package, array $providers, $re * set of packages is empty an impossible rule is generated. * * @param BasePackage[] $packages The set of packages to choose from - * @param int $reason A RULE_* constant describing the reason for + * @param Rule::RULE_* $reason A RULE_* constant describing the reason for * generating this rule * @param array $reasonData Additional data like the root require or fix request info * @return Rule The generated rule + * + * @phpstan-param ReasonData $reasonData */ protected function createInstallOneOfRule(array $packages, $reason, $reasonData) { @@ -92,13 +102,15 @@ protected function createInstallOneOfRule(array $packages, $reason, $reasonData) * The rule for conflicting packages A and B is (-A|-B). A is called the issuer * and B the provider. * - * @param BasePackage $issuer The package declaring the conflict - * @param BasePackage $provider The package causing the conflict - * @param int $reason A RULE_* constant describing the - * reason for generating this rule - * @param mixed $reasonData Any data, e.g. the package name, that - * goes with the reason - * @return Rule|null The generated rule + * @param BasePackage $issuer The package declaring the conflict + * @param BasePackage $provider The package causing the conflict + * @param Rule::RULE_* $reason A RULE_* constant describing the + * reason for generating this rule + * @param mixed $reasonData Any data, e.g. the package name, that + * goes with the reason + * @return Rule|null The generated rule + * + * @phpstan-param ReasonData $reasonData */ protected function createRule2Literals(BasePackage $issuer, BasePackage $provider, $reason, $reasonData = null) { @@ -144,11 +156,11 @@ private function addRule($type, Rule $newRule = null) protected function addRulesForPackage(BasePackage $package, $ignorePlatformReqs) { + /** @var \SplQueue */ $workQueue = new \SplQueue; $workQueue->enqueue($package); while (!$workQueue->isEmpty()) { - /** @var BasePackage $package */ $package = $workQueue->dequeue(); if (isset($this->addedMap[$package->id])) { continue; @@ -286,13 +298,6 @@ protected function addRulesForRootAliases($ignorePlatformReqs) */ public function getRulesFor(Request $request, $ignorePlatformReqs = false) { - $this->rules = new RuleSet; - - $this->addedMap = array(); - $this->conflictAddedMap = array(); - $this->addedPackagesByNames = array(); - $this->conflictsForName = array(); - $this->addRulesForRequest($request, $ignorePlatformReqs); $this->addRulesForRootAliases($ignorePlatformReqs); @@ -300,8 +305,12 @@ public function getRulesFor(Request $request, $ignorePlatformReqs = false) $this->addConflictRules($ignorePlatformReqs); // Remove references to packages - $this->addedMap = $this->addedPackagesByNames = null; + $this->addedMap = $this->addedPackagesByNames = array(); + + $rules = $this->rules; + + $this->rules = new RuleSet; - return $this->rules; + return $rules; } } diff --git a/src/Composer/DependencyResolver/RuleSetIterator.php b/src/Composer/DependencyResolver/RuleSetIterator.php index e755572a06ad..2726253d236b 100644 --- a/src/Composer/DependencyResolver/RuleSetIterator.php +++ b/src/Composer/DependencyResolver/RuleSetIterator.php @@ -14,16 +14,25 @@ /** * @author Nils Adermann + * @implements \Iterator */ class RuleSetIterator implements \Iterator { + /** @var array */ protected $rules; + /** @var array */ protected $types; + /** @var int */ protected $currentOffset; + /** @var RuleSet::TYPE_*|-1 */ protected $currentType; + /** @var int */ protected $currentTypeOffset; + /** + * @param array $rules + */ public function __construct(array $rules) { $this->rules = $rules; diff --git a/src/Composer/DependencyResolver/RuleWatchChain.php b/src/Composer/DependencyResolver/RuleWatchChain.php index 2fea0d6ee2eb..52795ea899db 100644 --- a/src/Composer/DependencyResolver/RuleWatchChain.php +++ b/src/Composer/DependencyResolver/RuleWatchChain.php @@ -19,11 +19,10 @@ * method to set the internal iterator to a particular offset. * * @author Nils Adermann + * @extends \SplDoublyLinkedList */ class RuleWatchChain extends \SplDoublyLinkedList { - protected $offset = 0; - /** * Moves the internal iterator to the specified offset * diff --git a/src/Composer/DependencyResolver/RuleWatchGraph.php b/src/Composer/DependencyResolver/RuleWatchGraph.php index 42bcfd551ef4..76b6abb55005 100644 --- a/src/Composer/DependencyResolver/RuleWatchGraph.php +++ b/src/Composer/DependencyResolver/RuleWatchGraph.php @@ -24,6 +24,7 @@ */ class RuleWatchGraph { + /** @var array */ protected $watchChains = array(); /** @@ -153,7 +154,7 @@ public function propagateLiteral($decidedLiteral, $level, $decisions) * @param int $toLiteral A literal the node should watch now * @param RuleWatchNode $node The rule node to be moved */ - protected function moveWatch($fromLiteral, $toLiteral, $node) + protected function moveWatch($fromLiteral, $toLiteral, RuleWatchNode $node) { if (!isset($this->watchChains[$toLiteral])) { $this->watchChains[$toLiteral] = new RuleWatchChain; diff --git a/src/Composer/DependencyResolver/RuleWatchNode.php b/src/Composer/DependencyResolver/RuleWatchNode.php index 0986b08b1140..24fccd8d3e01 100644 --- a/src/Composer/DependencyResolver/RuleWatchNode.php +++ b/src/Composer/DependencyResolver/RuleWatchNode.php @@ -21,9 +21,12 @@ */ class RuleWatchNode { + /** @var int */ public $watch1; + /** @var int */ public $watch2; + /** @var Rule */ protected $rule; /** @@ -31,7 +34,7 @@ class RuleWatchNode * * @param Rule $rule The rule to wrap */ - public function __construct($rule) + public function __construct(Rule $rule) { $this->rule = $rule; diff --git a/src/Composer/DependencyResolver/Solver.php b/src/Composer/DependencyResolver/Solver.php index 4b5330923a9f..7454ea74ef42 100644 --- a/src/Composer/DependencyResolver/Solver.php +++ b/src/Composer/DependencyResolver/Solver.php @@ -45,9 +45,9 @@ class Solver protected $branches = array(); /** @var Problem[] */ protected $problems = array(); - /** @var array */ + /** @var array */ protected $learnedPool = array(); - /** @var array */ + /** @var array */ protected $learnedWhy = array(); /** @var bool */ diff --git a/src/Composer/DependencyResolver/SolverProblemsException.php b/src/Composer/DependencyResolver/SolverProblemsException.php index fecce8036287..93eab3e63ebb 100644 --- a/src/Composer/DependencyResolver/SolverProblemsException.php +++ b/src/Composer/DependencyResolver/SolverProblemsException.php @@ -14,15 +14,22 @@ use Composer\Util\IniHelper; use Composer\Repository\RepositorySet; +use Composer\Package\PackageInterface; /** * @author Nils Adermann */ class SolverProblemsException extends \RuntimeException { + /** @var Problem[] */ protected $problems; + /** @var array */ protected $learnedPool; + /** + * @param Problem[] $problems + * @param array $learnedPool + */ public function __construct(array $problems, array $learnedPool) { $this->problems = $problems; diff --git a/src/Composer/DependencyResolver/Transaction.php b/src/Composer/DependencyResolver/Transaction.php index 66b9b9a3e006..1cda16927f59 100644 --- a/src/Composer/DependencyResolver/Transaction.php +++ b/src/Composer/DependencyResolver/Transaction.php @@ -16,6 +16,7 @@ use Composer\Package\Link; use Composer\Package\PackageInterface; use Composer\Repository\PlatformRepository; +use Composer\DependencyResolver\Operation\OperationInterface; /** * @author Nils Adermann @@ -24,24 +25,24 @@ class Transaction { /** - * @var array + * @var OperationInterface[] */ protected $operations; /** * Packages present at the beginning of the transaction - * @var array + * @var PackageInterface[] */ protected $presentPackages; /** * Package set resulting from this transaction - * @var array + * @var array */ protected $resultPackageMap; /** - * @var array + * @var array */ protected $resultPackagesByName = array(); @@ -52,6 +53,7 @@ public function __construct($presentPackages, $resultPackages) $this->operations = $this->calculateOperations(); } + /** @return OperationInterface[] */ public function getOperations() { return $this->operations; @@ -201,7 +203,7 @@ protected function calculateOperations() * These serve as a starting point to enumerate packages in a topological order despite potential cycles. * If there are packages with a cycle on the top level the package with the lowest name gets picked * - * @return array + * @return array */ protected function getRootPackages() { @@ -245,8 +247,8 @@ protected function getProvidersInResult(Link $link) * it at least fixes the symptoms and makes usage of composer possible (again) * in such scenarios. * - * @param Operation\OperationInterface[] $operations - * @return Operation\OperationInterface[] reordered operation list + * @param OperationInterface[] $operations + * @return OperationInterface[] reordered operation list */ private function movePluginsToFront(array $operations) { @@ -322,8 +324,8 @@ private function movePluginsToFront(array $operations) * Removals of packages should be executed before installations in * case two packages resolve to the same path (due to custom installers) * - * @param Operation\OperationInterface[] $operations - * @return Operation\OperationInterface[] reordered operation list + * @param OperationInterface[] $operations + * @return OperationInterface[] reordered operation list */ private function moveUninstallsToFront(array $operations) { diff --git a/src/Composer/Downloader/TransportException.php b/src/Composer/Downloader/TransportException.php index 68c73542fb4e..a478e580764f 100644 --- a/src/Composer/Downloader/TransportException.php +++ b/src/Composer/Downloader/TransportException.php @@ -17,9 +17,13 @@ */ class TransportException extends \RuntimeException { + /** @var ?array */ protected $headers; + /** @var ?string */ protected $response; + /** @var ?int */ protected $statusCode; + /** @var ?array */ protected $responseInfo = array(); public function setHeaders($headers) diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php index b44c7264bdec..53c573679966 100644 --- a/src/Composer/Downloader/VcsDownloader.php +++ b/src/Composer/Downloader/VcsDownloader.php @@ -38,7 +38,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa protected $process; /** @var Filesystem */ protected $filesystem; - /** @var array */ + /** @var array */ protected $hasCleanedChanges = array(); public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null) diff --git a/src/Composer/Downloader/ZipDownloader.php b/src/Composer/Downloader/ZipDownloader.php index 8049db9f47c1..2a93c9f9c082 100644 --- a/src/Composer/Downloader/ZipDownloader.php +++ b/src/Composer/Downloader/ZipDownloader.php @@ -25,8 +25,11 @@ */ class ZipDownloader extends ArchiveDownloader { + /** @var array */ private static $unzipCommands; + /** @var bool */ private static $hasZipArchive; + /** @var bool */ private static $isWindows; /** @var ZipArchive|null */ diff --git a/src/Composer/Installer/BinaryInstaller.php b/src/Composer/Installer/BinaryInstaller.php index cdbd1074cd1a..c692e72b3ddb 100644 --- a/src/Composer/Installer/BinaryInstaller.php +++ b/src/Composer/Installer/BinaryInstaller.php @@ -28,9 +28,13 @@ */ class BinaryInstaller { + /** @var string */ protected $binDir; + /** @var string */ protected $binCompat; + /** @var IOInterface */ protected $io; + /** @var Filesystem */ protected $filesystem; /** diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index 82a32520a130..239e5d1292e7 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -20,6 +20,7 @@ use Composer\Util\Silencer; use Composer\Util\Platform; use React\Promise\PromiseInterface; +use Composer\Downloader\DownloadManager; /** * Package installation manager. @@ -29,14 +30,19 @@ */ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface { + /** @var Composer */ protected $composer; + /** @var string */ protected $vendorDir; - protected $binDir; + /** @var DownloadManager */ protected $downloadManager; + /** @var IOInterface */ protected $io; + /** @var string */ protected $type; + /** @var Filesystem */ protected $filesystem; - protected $binCompat; + /** @var BinaryInstaller */ protected $binaryInstaller; /** diff --git a/src/Composer/Installer/PluginInstaller.php b/src/Composer/Installer/PluginInstaller.php index b334ac43e07a..12025321637d 100644 --- a/src/Composer/Installer/PluginInstaller.php +++ b/src/Composer/Installer/PluginInstaller.php @@ -99,7 +99,7 @@ public function update(InstalledRepositoryInterface $repo, PackageInterface $ini return $promise->then(function () use ($self, $pluginManager, $initial, $target, $repo) { try { Platform::workaroundFilesystemIssues(); - $pluginManager->deactivatePackage($initial, true); + $pluginManager->deactivatePackage($initial); $pluginManager->registerPackage($target, true); } catch (\Exception $e) { $self->rollbackInstall($e, $repo, $target); @@ -109,7 +109,7 @@ public function update(InstalledRepositoryInterface $repo, PackageInterface $ini public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) { - $this->composer->getPluginManager()->uninstallPackage($package, true); + $this->composer->getPluginManager()->uninstallPackage($package); return parent::uninstall($repo, $package); } diff --git a/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php b/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php index 379fcf49ecc6..de6dba02313e 100644 --- a/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleSetIteratorTest.php @@ -17,6 +17,7 @@ use Composer\DependencyResolver\RuleSet; use Composer\DependencyResolver\RuleSetIterator; use Composer\DependencyResolver\Pool; +use Composer\Semver\Constraint\MatchAllConstraint; use Composer\Test\TestCase; class RuleSetIteratorTest extends TestCase @@ -30,11 +31,11 @@ protected function setUp() $this->rules = array( RuleSet::TYPE_REQUEST => array( - new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null), - new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null), + new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), + new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), ), RuleSet::TYPE_LEARNED => array( - new GenericRule(array(), Rule::RULE_LEARNED, null), + new GenericRule(array(), Rule::RULE_LEARNED, 1), ), RuleSet::TYPE_PACKAGE => array(), ); diff --git a/tests/Composer/Test/DependencyResolver/RuleSetTest.php b/tests/Composer/Test/DependencyResolver/RuleSetTest.php index 7ffe6ac490ce..68ac43ad1721 100644 --- a/tests/Composer/Test/DependencyResolver/RuleSetTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleSetTest.php @@ -16,6 +16,7 @@ use Composer\DependencyResolver\Rule; use Composer\DependencyResolver\RuleSet; use Composer\DependencyResolver\Pool; +use Composer\Semver\Constraint\MatchAllConstraint; use Composer\Semver\Constraint\MatchNoneConstraint; use Composer\Test\TestCase; @@ -26,11 +27,11 @@ public function testAdd() $rules = array( RuleSet::TYPE_PACKAGE => array(), RuleSet::TYPE_REQUEST => array( - new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null), - new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, null), + new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), + new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), ), RuleSet::TYPE_LEARNED => array( - new GenericRule(array(), Rule::RULE_LEARNED, null), + new GenericRule(array(), Rule::RULE_LEARNED, 1), ), ); @@ -47,9 +48,9 @@ public function testAddIgnoresDuplicates() { $rules = array( RuleSet::TYPE_REQUEST => array( - new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null), - new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null), - new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null), + new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), + new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), + new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), ), ); @@ -67,15 +68,15 @@ public function testAddWhenTypeIsNotRecognized() $ruleSet = new RuleSet; $this->setExpectedException('OutOfBoundsException'); - $ruleSet->add(new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null), 7); + $ruleSet->add(new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), 7); } public function testCount() { $ruleSet = new RuleSet; - $ruleSet->add(new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null), RuleSet::TYPE_REQUEST); - $ruleSet->add(new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, null), RuleSet::TYPE_REQUEST); + $ruleSet->add(new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), RuleSet::TYPE_REQUEST); + $ruleSet->add(new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), RuleSet::TYPE_REQUEST); $this->assertEquals(2, $ruleSet->count()); } @@ -84,7 +85,7 @@ public function testRuleById() { $ruleSet = new RuleSet; - $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $ruleSet->add($rule, RuleSet::TYPE_REQUEST); $this->assertSame($rule, $ruleSet->ruleById[0]); @@ -94,8 +95,8 @@ public function testGetIterator() { $ruleSet = new RuleSet; - $rule1 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, null); + $rule1 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $ruleSet->add($rule1, RuleSet::TYPE_REQUEST); $ruleSet->add($rule2, RuleSet::TYPE_LEARNED); @@ -109,8 +110,8 @@ public function testGetIterator() public function testGetIteratorFor() { $ruleSet = new RuleSet; - $rule1 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, null); + $rule1 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $ruleSet->add($rule1, RuleSet::TYPE_REQUEST); $ruleSet->add($rule2, RuleSet::TYPE_LEARNED); @@ -123,8 +124,8 @@ public function testGetIteratorFor() public function testGetIteratorWithout() { $ruleSet = new RuleSet; - $rule1 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, null); + $rule1 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(2), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $ruleSet->add($rule1, RuleSet::TYPE_REQUEST); $ruleSet->add($rule2, RuleSet::TYPE_LEARNED); diff --git a/tests/Composer/Test/DependencyResolver/RuleTest.php b/tests/Composer/Test/DependencyResolver/RuleTest.php index 3ff69c8cef68..18f57c685bb8 100644 --- a/tests/Composer/Test/DependencyResolver/RuleTest.php +++ b/tests/Composer/Test/DependencyResolver/RuleTest.php @@ -24,7 +24,7 @@ class RuleTest extends TestCase { public function testGetHash() { - $rule = new GenericRule(array(123), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(123), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $hash = unpack('ihash', md5('123', true)); $this->assertEquals($hash['hash'], $rule->getHash()); @@ -32,31 +32,31 @@ public function testGetHash() public function testEqualsForRulesWithDifferentHashes() { - $rule = new GenericRule(array(1, 2), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(1, 3), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(1, 2), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(1, 3), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $this->assertFalse($rule->equals($rule2)); } public function testEqualsForRulesWithDifferLiteralsQuantity() { - $rule = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $this->assertFalse($rule->equals($rule2)); } public function testEqualsForRulesWithSameLiterals() { - $rule = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $this->assertTrue($rule->equals($rule2)); } public function testSetAndGetType() { - $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $rule->setType(RuleSet::TYPE_REQUEST); $this->assertEquals(RuleSet::TYPE_REQUEST, $rule->getType()); @@ -64,7 +64,7 @@ public function testSetAndGetType() public function testEnable() { - $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $rule->disable(); $rule->enable(); @@ -74,7 +74,7 @@ public function testEnable() public function testDisable() { - $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $rule->enable(); $rule->disable(); @@ -84,8 +84,8 @@ public function testDisable() public function testIsAssertions() { - $rule = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, null); - $rule2 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, null); + $rule = new GenericRule(array(1, 12), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); + $rule2 = new GenericRule(array(1), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)); $this->assertFalse($rule->isAssertion()); $this->assertTrue($rule2->isAssertion()); diff --git a/tests/Composer/Test/DependencyResolver/TransactionTest.php b/tests/Composer/Test/DependencyResolver/TransactionTest.php index 39354c0063a8..f909fd0b63ee 100644 --- a/tests/Composer/Test/DependencyResolver/TransactionTest.php +++ b/tests/Composer/Test/DependencyResolver/TransactionTest.php @@ -12,6 +12,11 @@ namespace Composer\Test\DependencyResolver; +use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\DependencyResolver\Operation\MarkAliasInstalledOperation; +use Composer\DependencyResolver\Operation\MarkAliasUninstalledOperation; +use Composer\DependencyResolver\Operation\UninstallOperation; +use Composer\DependencyResolver\Operation\UpdateOperation; use Composer\DependencyResolver\Transaction; use Composer\Package\Link; use Composer\Test\TestCase; @@ -97,17 +102,19 @@ protected function checkTransactionOperations(Transaction $transaction, array $e { $result = array(); foreach ($transaction->getOperations() as $operation) { - if ('update' === $operation->getOperationType()) { + if ($operation instanceof UpdateOperation) { $result[] = array( 'job' => 'update', 'from' => $operation->getInitialPackage(), 'to' => $operation->getTargetPackage(), ); - } else { + } elseif ($operation instanceof InstallOperation || $operation instanceof UninstallOperation || $operation instanceof MarkAliasInstalledOperation || $operation instanceof MarkAliasUninstalledOperation) { $result[] = array( 'job' => $operation->getOperationType(), 'package' => $operation->getPackage(), ); + } else { + throw new \UnexpectedValueException('Unknown operation type: '.get_class($operation)); } }