Reaching phpstan level 6 in Composer/DependencyResolver (refs #10159) (#10178)

main
immeëmosol 3 years ago committed by GitHub
parent 04ab74bbef
commit 50d738eeee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,7 +16,7 @@ namespace Composer\DependencyResolver;
* Stores decisions on installing, removing or keeping packages
*
* @author Nils Adermann <naderman@naderman.de>
* @implements \Iterator<array{0: int, 1: mixed}>
* @implements \Iterator<array{0: int, 1: Rule}>
*/
class Decisions implements \Iterator, \Countable
{
@ -27,7 +27,9 @@ class Decisions implements \Iterator, \Countable
protected $pool;
/** @var array<int, int> */
protected $decisionMap;
/** @var array<array{0: int, 1: mixed}> */
/**
* @var array<array{0: int, 1: Rule}>
*/
protected $decisionQueue = array();
public function __construct(Pool $pool)
@ -36,7 +38,12 @@ class Decisions implements \Iterator, \Countable
$this->decisionMap = array();
}
public function decide($literal, $level, $why)
/**
* @param int $literal
* @param int $level
* @return void
*/
public function decide($literal, $level, Rule $why)
{
$this->addDecision($literal, $level);
$this->decisionQueue[] = array(
@ -46,6 +53,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literal
* @return bool
*/
public function satisfy($literal)
@ -59,6 +67,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literal
* @return bool
*/
public function conflict($literal)
@ -72,6 +81,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literalOrPackageId
* @return bool
*/
public function decided($literalOrPackageId)
@ -80,6 +90,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literalOrPackageId
* @return bool
*/
public function undecided($literalOrPackageId)
@ -88,6 +99,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literalOrPackageId
* @return bool
*/
public function decidedInstall($literalOrPackageId)
@ -98,6 +110,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literalOrPackageId
* @return int
*/
public function decisionLevel($literalOrPackageId)
@ -111,13 +124,14 @@ class Decisions implements \Iterator, \Countable
}
/**
* @return mixed|null
* @param int $literalOrPackageId
* @return Rule|null
*/
public function decisionRule($literalOrPackageId)
{
$packageId = abs($literalOrPackageId);
foreach ($this->decisionQueue as $i => $decision) {
foreach ($this->decisionQueue as $decision) {
if ($packageId === abs($decision[self::DECISION_LITERAL])) {
return $decision[self::DECISION_REASON];
}
@ -127,7 +141,8 @@ class Decisions implements \Iterator, \Countable
}
/**
* @return array{0: int, 1: mixed} a literal and decision reason
* @param int $queueOffset
* @return array{0: int, 1: Rule} a literal and decision reason
*/
public function atOffset($queueOffset)
{
@ -135,6 +150,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $queueOffset
* @return bool
*/
public function validOffset($queueOffset)
@ -143,7 +159,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @return mixed
* @return Rule
*/
public function lastReason()
{
@ -169,6 +185,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $offset
* @return void
*/
public function resetToOffset($offset)
@ -207,7 +224,7 @@ class Decisions implements \Iterator, \Countable
}
/**
* @return array{0: int, 1: mixed}|false
* @return array{0: int, 1: Rule}|false
*/
#[\ReturnTypeWillChange]
public function current()
@ -251,6 +268,8 @@ class Decisions implements \Iterator, \Countable
}
/**
* @param int $literal
* @param int $level
* @return void
*/
protected function addDecision($literal, $level)
@ -289,9 +308,6 @@ class Decisions implements \Iterator, \Countable
return $str;
}
/**
* @return string
*/
public function __toString()
{
return $this->toString();

@ -28,6 +28,10 @@ class DefaultPolicy implements PolicyInterface
/** @var bool */
private $preferLowest;
/**
* @param bool $preferStable
* @param bool $preferLowest
*/
public function __construct($preferStable = false, $preferLowest = false)
{
$this->preferStable = $preferStable;
@ -35,7 +39,10 @@ class DefaultPolicy implements PolicyInterface
}
/**
* @param string $operator One of Constraint::STR_OP_*
* @return bool
*
* @phpstan-param Constraint::STR_OP_* $operator
*/
public function versionCompare(PackageInterface $a, PackageInterface $b, $operator)
{
@ -101,6 +108,8 @@ class DefaultPolicy implements PolicyInterface
/**
* @protected
* @param ?string $requiredPackage
* @param bool $ignoreReplace
* @return int
*/
public function compareByPriority(Pool $pool, BasePackage $a, BasePackage $b, $requiredPackage = null, $ignoreReplace = false)
@ -154,8 +163,6 @@ class DefaultPolicy implements PolicyInterface
* Replace constraints are ignored. This method should only be used for
* prioritisation, not for actual constraint verification.
*
* @param BasePackage $source
* @param BasePackage $target
* @return bool
*/
protected function replaces(BasePackage $source, BasePackage $target)

@ -12,10 +12,6 @@
namespace Composer\DependencyResolver;
use Composer\Package\BasePackage;
use Composer\Package\Link;
use Composer\Semver\Constraint\ConstraintInterface;
/**
* @author Nils Adermann <naderman@naderman.de>
*/
@ -25,7 +21,7 @@ class GenericRule extends Rule
protected $literals;
/**
* @param int[] $literals
* @param int[] $literals
*/
public function __construct(array $literals, $reason, $reasonData)
{
@ -45,6 +41,9 @@ class GenericRule extends Rule
return $this->literals;
}
/**
* @inheritDoc
*/
public function getHash()
{
$data = unpack('ihash', md5(implode(',', $this->literals), true));

@ -12,6 +12,7 @@
namespace Composer\DependencyResolver;
use Composer\Repository\InstalledRepositoryInterface;
use Composer\Repository\RepositoryInterface;
/**
@ -20,7 +21,7 @@ use Composer\Repository\RepositoryInterface;
*/
class LocalRepoTransaction extends Transaction
{
public function __construct(RepositoryInterface $lockedRepository, $localRepository)
public function __construct(RepositoryInterface $lockedRepository, InstalledRepositoryInterface $localRepository)
{
parent::__construct(
$localRepository->getPackages(),

@ -58,7 +58,11 @@ class LockTransaction extends Transaction
parent::__construct($this->presentMap, $this->resultPackages['all']);
}
// TODO make this a bit prettier instead of the two text indexes?
/**
* @return void
*/
public function setResultPackages(Pool $pool, Decisions $decisions)
{
$this->resultPackages = array('all' => array(), 'non-dev' => array(), 'dev' => array());
@ -76,6 +80,9 @@ class LockTransaction extends Transaction
}
}
/**
* @return void
*/
public function setNonDevPackages(LockTransaction $extractionResult)
{
$packages = $extractionResult->getNewLockPackages(false);
@ -96,6 +103,8 @@ class LockTransaction extends Transaction
// TODO additionalFixedRepository needs to be looked at here as well?
/**
* @param bool $devMode
* @param bool $updateMirrors
* @return BasePackage[]
*/
public function getNewLockPackages($devMode, $updateMirrors = false)
@ -126,6 +135,8 @@ class LockTransaction extends Transaction
/**
* Checks which of the given aliases from composer.json are actually in use for the lock file
* @param array<array{package: string, version: string, alias: string, alias_normalized: string}> $aliases
* @return array<array{package: string, version: string, alias: string, alias_normalized: string}>
*/
public function getAliases($aliases)
{

@ -12,9 +12,6 @@
namespace Composer\DependencyResolver;
use Composer\Package\BasePackage;
use Composer\Package\Link;
/**
* @author Nils Adermann <naderman@naderman.de>
*
@ -26,7 +23,7 @@ class MultiConflictRule extends Rule
protected $literals;
/**
* @param int[] $literals
* @param int[] $literals
*/
public function __construct(array $literals, $reason, $reasonData)
{
@ -50,6 +47,9 @@ class MultiConflictRule extends Rule
return $this->literals;
}
/**
* @inheritDoc
*/
public function getHash()
{
$data = unpack('ihash', md5('c:'.implode(',', $this->literals), true));
@ -82,6 +82,10 @@ class MultiConflictRule extends Rule
return false;
}
/**
* @return never
* @throws \RuntimeException
*/
public function disable()
{
throw new \RuntimeException("Disabling multi conflict rules is not possible. Please contact composer at https://github.com/composer/composer to let us debug what lead to this situation.");

@ -52,6 +52,7 @@ class InstallOperation extends SolverOperation implements OperationInterface
}
/**
* @param bool $lock
* @return string
*/
public static function format(PackageInterface $package, $lock = false)

@ -52,6 +52,7 @@ class UninstallOperation extends SolverOperation implements OperationInterface
}
/**
* @param bool $lock
* @return string
*/
public static function format(PackageInterface $package, $lock = false)

@ -73,6 +73,7 @@ class UpdateOperation extends SolverOperation implements OperationInterface
}
/**
* @param bool $lock
* @return string
*/
public static function format(PackageInterface $initialPackage, PackageInterface $targetPackage, $lock = false)

@ -12,11 +12,11 @@
namespace Composer\DependencyResolver;
use Composer\Package\BasePackage;
use Composer\Package\Version\VersionParser;
use Composer\Semver\CompilingMatcher;
use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Constraint\Constraint;
use Composer\Package\BasePackage;
/**
* A package pool contains all packages for dependency resolution
@ -37,6 +37,10 @@ class Pool implements \Countable
/** @var BasePackage[] */
protected $unacceptableFixedOrLockedPackages;
/**
* @param BasePackage[] $packages
* @param BasePackage[] $unacceptableFixedOrLockedPackages
*/
public function __construct(array $packages = array(), array $unacceptableFixedOrLockedPackages = array())
{
$this->versionParser = new VersionParser;
@ -44,6 +48,10 @@ class Pool implements \Countable
$this->unacceptableFixedOrLockedPackages = $unacceptableFixedOrLockedPackages;
}
/**
* @param BasePackage[] $packages
* @return void
*/
private function setPackages(array $packages)
{
$id = 1;
@ -91,10 +99,10 @@ class Pool implements \Countable
/**
* Searches all packages providing the given package name and match the constraint
*
* @param string $name The package name to be searched for
* @param ConstraintInterface $constraint A constraint that all returned
* @param string $name The package name to be searched for
* @param ?ConstraintInterface $constraint A constraint that all returned
* packages must match or null to return all
* @return BasePackage[] A set of packages
* @return BasePackage[] A set of packages
*/
public function whatProvides($name, ConstraintInterface $constraint = null)
{
@ -130,6 +138,7 @@ class Pool implements \Countable
}
/**
* @param int $literal
* @return BasePackage
*/
public function literalToPackage($literal)
@ -140,6 +149,8 @@ class Pool implements \Countable
}
/**
* @param int $literal
* @param array<int, BasePackage> $installedMap
* @return string
*/
public function literalToPrettyString($literal, $installedMap)
@ -159,9 +170,7 @@ class Pool implements \Countable
* Checks if the package matches the given constraint directly or through
* provided or replaced packages
*
* @param BasePackage $candidate
* @param string $name Name of the package to be matched
* @param ConstraintInterface $constraint The constraint to verify
* @return bool
*/
public function match(BasePackage $candidate, $name, ConstraintInterface $constraint = null)

@ -18,12 +18,13 @@ use Composer\Package\AliasPackage;
use Composer\Package\BasePackage;
use Composer\Package\CompleteAliasPackage;
use Composer\Package\CompletePackage;
use Composer\Package\CompletePackageInterface;
use Composer\Package\PackageInterface;
use Composer\Package\Version\StabilityFilter;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PrePoolCreateEvent;
use Composer\Repository\LockArrayRepository;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RootPackageRepository;
use Composer\Semver\CompilingMatcher;
use Composer\Semver\Constraint\Constraint;
@ -86,12 +87,11 @@ class PoolBuilder
*/
private $loadedPerRepo = array();
/**
* @var PackageInterface[]
* @var BasePackage[]
*/
private $packages = array();
/**
* @var PackageInterface[]
* @phpstan-var list<PackageInterface>
* @var BasePackage[]
*/
private $unacceptableFixedOrLockedPackages = array();
/** @var string[] */
@ -140,6 +140,7 @@ class PoolBuilder
}
/**
* @param RepositoryInterface[] $repositories
* @return Pool
*/
public function buildPool(array $repositories, Request $request)
@ -265,6 +266,7 @@ class PoolBuilder
}
/**
* @param string $name
* @return void
*/
private function markPackageNameForLoading(Request $request, $name, ConstraintInterface $constraint)
@ -323,6 +325,7 @@ class PoolBuilder
}
/**
* @param RepositoryInterface[] $repositories
* @return void
*/
private function loadPackagesMarkedForLoading(Request $request, $repositories)
@ -358,6 +361,7 @@ class PoolBuilder
}
/**
* @param bool $propagateUpdate
* @return void
*/
private function loadPackage(Request $request, BasePackage $package, $propagateUpdate = true)
@ -446,6 +450,7 @@ class PoolBuilder
/**
* Checks if a particular name is required directly in the request
*
* @param string $name packageName
* @return bool
*/
private function isRootRequire(Request $request, $name)
@ -460,7 +465,7 @@ class PoolBuilder
*
* @return bool
*/
private function isUpdateAllowed(PackageInterface $package)
private function isUpdateAllowed(BasePackage $package)
{
// Path repo packages are never loaded from lock, to force them to always remain in sync
// unless symlinking is disabled in which case we probably should rather treat them like
@ -513,6 +518,7 @@ class PoolBuilder
* Reverts the decision to use a locked package if a partial update with transitive dependencies
* found that this package actually needs to be updated
*
* @param string $name
* @return void
*/
private function unlockPackage(Request $request, $name)
@ -553,9 +559,10 @@ class PoolBuilder
}
/**
* @param int $index
* @return void
*/
private function removeLoadedPackage(Request $request, PackageInterface $package, $index)
private function removeLoadedPackage(Request $request, BasePackage $package, $index)
{
unset($this->packages[$index]);
if (isset($this->aliasMap[spl_object_hash($package)])) {

@ -14,6 +14,8 @@ namespace Composer\DependencyResolver;
use Composer\Package\CompletePackageInterface;
use Composer\Package\AliasPackage;
use Composer\Package\BasePackage;
use Composer\Package\PackageInterface;
use Composer\Package\RootPackageInterface;
use Composer\Repository\RepositorySet;
use Composer\Repository\LockArrayRepository;
@ -47,6 +49,7 @@ class Problem
* Add a rule as a reason
*
* @param Rule $rule A rule which is a reason for this problem
* @return void
*/
public function addRule(Rule $rule)
{
@ -56,7 +59,7 @@ class Problem
/**
* Retrieve all reasons for this problem
*
* @return array The problem's reasons
* @return array<int, array<int, Rule>> The problem's reasons
*/
public function getReasons()
{
@ -66,7 +69,9 @@ class Problem
/**
* A human readable textual representation of the problem's reasons
*
* @param array $installedMap A map of all present packages
* @param bool $isVerbose
* @param array<int|string, BasePackage> $installedMap A map of all present packages
* @param array<Rule[]> $learnedPool
* @return string
*/
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, array $installedMap = array(), array $learnedPool = array())
@ -101,8 +106,13 @@ class Problem
}
/**
* @internal
* @param Rule[] $rules
* @param string $indent
* @param bool $isVerbose
* @param array<int|string, BasePackage> $installedMap A map of all present packages
* @param array<Rule[]> $learnedPool
* @return string
* @internal
*/
public static function formatDeduplicatedRules($rules, $indent, RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, array $installedMap = array(), array $learnedPool = array())
{
@ -166,7 +176,6 @@ class Problem
*
* @param string $id A canonical identifier for the reason
* @param Rule $reason The reason descriptor
*
* @return void
*/
protected function addReason($id, Rule $reason)
@ -190,9 +199,11 @@ class Problem
/**
* @internal
* @param bool $isVerbose
* @param string $packageName
* @return array{0: string, 1: string}
*/
public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, $packageName, $constraint = null)
public static function getMissingPackageReason(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, $packageName, ConstraintInterface $constraint = null)
{
// handle php/hhvm
if ($packageName === 'php' || $packageName === 'php-64bit' || $packageName === 'hhvm') {
@ -343,6 +354,8 @@ class Problem
/**
* @internal
* @param PackageInterface[] $packages
* @param bool $isVerbose
* @return string
*/
public static function getPackageList(array $packages, $isVerbose)
@ -395,7 +408,9 @@ class Problem
}
/**
* @param string[] $versions an array of pretty versions, with normalized versions as keys
* @param string[] $versions an array of pretty versions, with normalized versions as keys
* @param int $max
* @param int $maxDev
* @return list<string> a list of pretty versions and '...' where versions were removed
*/
private static function condenseVersionList(array $versions, $max, $maxDev = 16)
@ -429,6 +444,7 @@ class Problem
}
/**
* @param PackageInterface[] $packages
* @return bool
*/
private static function hasMultipleNames(array $packages)
@ -446,6 +462,12 @@ class Problem
}
/**
* @param bool $isVerbose
* @param string $packageName
* @param ?ConstraintInterface $constraint
* @param PackageInterface[] $higherRepoPackages
* @param PackageInterface[] $allReposPackages
* @param string $reason
* @return array{0: string, 1: string}
*/
private static function computeCheckForLowerPrioRepo($isVerbose, $packageName, $constraint, array $higherRepoPackages, array $allReposPackages, $reason)

@ -12,8 +12,8 @@
namespace Composer\DependencyResolver;
use Composer\Package\Package;
use Composer\Package\BasePackage;
use Composer\Package\PackageInterface;
use Composer\Repository\LockArrayRepository;
use Composer\Semver\Constraint\ConstraintInterface;
use Composer\Semver\Constraint\MatchAllConstraint;
@ -60,6 +60,10 @@ class Request
$this->lockedRepository = $lockedRepository;
}
/**
* @param string $packageName
* @return void
*/
public function requireName($packageName, ConstraintInterface $constraint = null)
{
$packageName = strtolower($packageName);
@ -78,6 +82,8 @@ class Request
*
* This is used for platform packages which cannot be modified by Composer. A rule enforcing their installation is
* generated for dependency resolution. Partial updates with dependencies cannot in any way modify these packages.
*
* @return void
*/
public function fixPackage(BasePackage $package)
{
@ -93,6 +99,8 @@ class Request
* However unlike fixed packages there will not be a special rule enforcing their installation for the solver, so
* if nothing requires these packages they will be removed. Additionally in a partial update these packages can be
* unlocked, meaning other versions can be installed if explicitly requested as part of the update.
*
* @return void
*/
public function lockPackage(BasePackage $package)
{
@ -105,6 +113,8 @@ class Request
* This is necessary for the composer install step which verifies the lock file integrity and should not allow
* removal of any packages. At the same time lock packages there cannot simply be marked fixed, as error reporting
* would then report them as platform packages, so this still marks them as locked packages at the same time.
*
* @return void
*/
public function fixLockedPackage(BasePackage $package)
{
@ -112,11 +122,19 @@ class Request
$this->fixedLockedPackages[spl_object_hash($package)] = $package;
}
/**
* @return void
*/
public function unlockPackage(BasePackage $package)
{
unset($this->lockedPackages[spl_object_hash($package)]);
}
/**
* @param string[] $updateAllowList
* @param false|self::UPDATE_* $updateAllowTransitiveDependencies
* @return void
*/
public function setUpdateAllowList($updateAllowList, $updateAllowTransitiveDependencies)
{
$this->updateAllowList = $updateAllowList;
@ -182,7 +200,7 @@ class Request
/**
* @return bool
*/
public function isLockedPackage(BasePackage $package)
public function isLockedPackage(PackageInterface $package)
{
return isset($this->lockedPackages[spl_object_hash($package)]) || isset($this->fixedLockedPackages[spl_object_hash($package)]);
}
@ -195,10 +213,14 @@ class Request
return array_merge($this->fixedPackages, $this->lockedPackages);
}
// TODO look into removing the packageIds option, the only place true is used is for the installed map in the solver problems
// some locked packages may not be in the pool so they have a package->id of -1
/**
* @param bool $packageIds
* @return array<int|string, BasePackage>
*
* @TODO look into removing the packageIds option, the only place true is used
* is for the installed map in the solver problems.
* Some locked packages may not be in the pool,
* so they have a package->id of -1
*/
public function getPresentMap($packageIds = false)
{

@ -12,11 +12,11 @@
namespace Composer\DependencyResolver;
use Composer\Package\Link;
use Composer\Package\BasePackage;
use Composer\Package\AliasPackage;
use Composer\Repository\RepositorySet;
use Composer\Package\BasePackage;
use Composer\Package\Link;
use Composer\Repository\PlatformRepository;
use Composer\Repository\RepositorySet;
use Composer\Package\Version\VersionParser;
use Composer\Semver\Constraint\Constraint;
use Composer\Semver\Constraint\ConstraintInterface;
@ -54,8 +54,8 @@ abstract class Rule
protected $reasonData;
/**
* @param self::RULE_* $reason A RULE_* constant describing the reason for generating this rule
* @param Link|BasePackage|ConstraintInterface|string $reasonData
* @param self::RULE_* $reason A RULE_* constant describing the reason for generating this rule
* @param mixed $reasonData
*
* @phpstan-param ReasonData $reasonData
*/
@ -68,26 +68,42 @@ abstract class Rule
(255 << self::BITFIELD_TYPE);
}
/**
* @return int[]
*/
abstract public function getLiterals();
/**
* @return int|string
*/
abstract public function getHash();
abstract public function __toString();
/**
* @param Rule $rule
* @return bool
*/
abstract public function equals(Rule $rule);
/**
* @return int
*/
public function getReason()
{
return ($this->bitfield & (255 << self::BITFIELD_REASON)) >> self::BITFIELD_REASON;
}
/**
* @phpstan-return ReasonData
*/
public function getReasonData()
{
return $this->reasonData;
}
/**
* @return ?string
* @return string|null
*/
public function getRequiredPackage()
{
@ -108,38 +124,63 @@ abstract class Rule
return null;
}
/**
* @param 255|RuleSet::TYPE_* $type
* @return void
*/
public function setType($type)
{
$this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_TYPE)) | ((255 & $type) << self::BITFIELD_TYPE);
}
/**
* @return int
*/
public function getType()
{
return ($this->bitfield & (255 << self::BITFIELD_TYPE)) >> self::BITFIELD_TYPE;
}
/**
* @return void
*/
public function disable()
{
$this->bitfield = ($this->bitfield & ~(255 << self::BITFIELD_DISABLED)) | (1 << self::BITFIELD_DISABLED);
}
/**
* @return void
*/
public function enable()
{
$this->bitfield &= ~(255 << self::BITFIELD_DISABLED);
}
/**
* @return bool
*/
public function isDisabled()
{
return (bool) (($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
}
/**
* @return bool
*/
public function isEnabled()
{
return !(($this->bitfield & (255 << self::BITFIELD_DISABLED)) >> self::BITFIELD_DISABLED);
}
/**
* @return bool
*/
abstract public function isAssertion();
/**
* @return bool
*/
public function isCausedByLock(RepositorySet $repositorySet, Request $request, Pool $pool)
{
if ($this->getReason() === self::RULE_PACKAGE_REQUIRES) {
@ -187,6 +228,12 @@ abstract class Rule
return false;
}
/**
* @param bool $isVerbose
* @param BasePackage[] $installedMap
* @param array<Rule[]> $learnedPool
* @return string
*/
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, array $installedMap = array(), array $learnedPool = array())
{
$literals = $this->getLiterals();
@ -396,12 +443,11 @@ abstract class Rule
}
/**
* @param Pool $pool
* @param array $packages
*
* @param array<int|BasePackage> $packages An array containing packages or literals
* @param bool $isVerbose
* @return string
*/
protected function formatPackagesUnique($pool, array $packages, $isVerbose)
protected function formatPackagesUnique(Pool $pool, array $packages, $isVerbose)
{
foreach ($packages as $index => $package) {
if (!\is_object($package)) {
@ -412,6 +458,9 @@ abstract class Rule
return Problem::getPackageList($packages, $isVerbose);
}
/**
* @return BasePackage
*/
private function deduplicateDefaultBranchAlias(BasePackage $package)
{
if ($package instanceof AliasPackage && $package->getPrettyVersion() === VersionParser::DEFAULT_BRANCH_ALIAS) {

@ -12,11 +12,9 @@
namespace Composer\DependencyResolver;
use Composer\Package\BasePackage;
use Composer\Package\Link;
/**
* @author Nils Adermann <naderman@naderman.de>
* @phpstan-import-type ReasonData from Rule
*/
class Rule2Literals extends Rule
{
@ -26,8 +24,12 @@ class Rule2Literals extends Rule
protected $literal2;
/**
* @param int $literal1
* @param int $literal2
* @param int $literal1
* @param int $literal2
* @param Rule::RULE_* $reason A RULE_* constant
* @param mixed $reasonData
*
* @phpstan-param ReasonData $reasonData
*/
public function __construct($literal1, $literal2, $reason, $reasonData)
{
@ -48,7 +50,9 @@ class Rule2Literals extends Rule
return array($this->literal1, $this->literal2);
}
/** @return string */
/**
* @inheritDoc
*/
public function getHash()
{
return $this->literal1.','.$this->literal2;

@ -56,6 +56,10 @@ class RuleSet implements \IteratorAggregate, \Countable
}
}
/**
* @param 255|self::TYPE_* $type
* @return void
*/
public function add(Rule $rule, $type)
{
if (!isset(self::$types[$type])) {
@ -110,6 +114,7 @@ class RuleSet implements \IteratorAggregate, \Countable
}
/**
* @param int $id
* @return Rule
*/
public function ruleById($id)
@ -155,6 +160,7 @@ class RuleSet implements \IteratorAggregate, \Countable
}
/**
* @param array<self::TYPE_*>|self::TYPE_* $types
* @return RuleSetIterator
*/
public function getIteratorWithout($types)
@ -182,6 +188,7 @@ class RuleSet implements \IteratorAggregate, \Countable
}
/**
* @param bool $isVerbose
* @return string
*/
public function getPrettyString(RepositorySet $repositorySet = null, Request $request = null, Pool $pool = null, $isVerbose = false)

@ -14,7 +14,6 @@ namespace Composer\DependencyResolver;
use Composer\Package\BasePackage;
use Composer\Package\AliasPackage;
use Composer\Package\PackageInterface;
use Composer\Repository\PlatformRepository;
/**
@ -29,9 +28,9 @@ class RuleSetGenerator
protected $pool;
/** @var RuleSet */
protected $rules;
/** @var array<int, PackageInterface> */
/** @var array<int, BasePackage> */
protected $addedMap = array();
/** @var array<string, PackageInterface[]> */
/** @var array<string, BasePackage[]> */
protected $addedPackagesByNames = array();
public function __construct(PolicyInterface $policy, Pool $pool)
@ -47,13 +46,11 @@ class RuleSetGenerator
* 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 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
* @param BasePackage $package The package with a requirement
* @param BasePackage[] $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
*/
@ -102,13 +99,11 @@ class RuleSetGenerator
* 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 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
* @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 The generated rule
*
* @phpstan-param ReasonData $reasonData
*/
@ -123,9 +118,14 @@ class RuleSetGenerator
}
/**
* @param BasePackage[] $packages
* @param Rule::RULE_* $reason A RULE_* constant
* @param mixed $reasonData
* @return Rule
*
* @phpstan-param ReasonData $reasonData
*/
protected function createMultiConflictRule(array $packages, $reason, $reasonData = null)
protected function createMultiConflictRule(array $packages, $reason, $reasonData)
{
$literals = array();
foreach ($packages as $package) {
@ -145,7 +145,7 @@ class RuleSetGenerator
* To be able to directly pass in the result of one of the rule creation
* methods null is allowed which will not insert a rule.
*
* @param int $type A TYPE_* constant defining the rule type
* @param 255|RuleSet::TYPE_* $type A TYPE_* constant defining the rule type
* @param Rule $newRule The rule about to be added
*
* @return void
@ -160,6 +160,7 @@ class RuleSetGenerator
}
/**
* @param bool|string[] $ignorePlatformReqs
* @return void
*/
protected function addRulesForPackage(BasePackage $package, $ignorePlatformReqs)
@ -211,6 +212,7 @@ class RuleSetGenerator
}
/**
* @param bool|string[] $ignorePlatformReqs
* @return void
*/
protected function addConflictRules($ignorePlatformReqs = false)
@ -249,6 +251,7 @@ class RuleSetGenerator
}
/**
* @param bool|string[] $ignorePlatformReqs
* @return void
*/
protected function addRulesForRequest(Request $request, $ignorePlatformReqs)
@ -293,6 +296,7 @@ class RuleSetGenerator
}
/**
* @param bool|string[] $ignorePlatformReqs
* @return void
*/
protected function addRulesForRootAliases($ignorePlatformReqs)
@ -311,7 +315,7 @@ class RuleSetGenerator
}
/**
* @param bool|array $ignorePlatformReqs
* @param bool|string[] $ignorePlatformReqs
* @return RuleSet
*/
public function getRulesFor(Request $request, $ignorePlatformReqs = false)

@ -27,6 +27,7 @@ class RuleWatchChain extends \SplDoublyLinkedList
* Moves the internal iterator to the specified offset
*
* @param int $offset The offset to seek to.
* @return void
*/
public function seek($offset)
{
@ -41,6 +42,8 @@ class RuleWatchChain extends \SplDoublyLinkedList
* incorrectly sets the internal iterator if you delete the current value
* this method sets the internal iterator back to the following element
* using the seek method.
*
* @return void
*/
public function remove()
{

@ -38,6 +38,7 @@ class RuleWatchGraph
* watch changes in any literals.
*
* @param RuleWatchNode $node The rule node to be inserted into the graph
* @return void
*/
public function insert(RuleWatchNode $node)
{
@ -87,7 +88,7 @@ class RuleWatchGraph
* register decisions resulting from propagation
* @return Rule|null If a conflict is found the conflicting rule is returned
*/
public function propagateLiteral($decidedLiteral, $level, $decisions)
public function propagateLiteral($decidedLiteral, $level, Decisions $decisions)
{
// we invert the decided literal here, example:
// A was decided => (-A|B) now requires B to be true, so we look for
@ -153,6 +154,7 @@ class RuleWatchGraph
* @param int $fromLiteral A literal the node used to watch
* @param int $toLiteral A literal the node should watch now
* @param RuleWatchNode $node The rule node to be moved
* @return void
*/
protected function moveWatch($fromLiteral, $toLiteral, RuleWatchNode $node)
{

@ -52,6 +52,7 @@ class RuleWatchNode
* likely to quickly lead to further decisions.
*
* @param Decisions $decisions The decisions made so far by the solver
* @return void
*/
public function watch2OnHighest(Decisions $decisions)
{
@ -104,6 +105,7 @@ class RuleWatchNode
*
* @param int $from The previously watched literal
* @param int $to The literal to be watched now
* @return void
*/
public function moveWatch($from, $to)
{

@ -56,11 +56,6 @@ class Solver
/** @var IOInterface */
protected $io;
/**
* @param PolicyInterface $policy
* @param Pool $pool
* @param IOInterface $io
*/
public function __construct(PolicyInterface $policy, Pool $pool, IOInterface $io)
{
$this->io = $io;
@ -171,9 +166,7 @@ class Solver
}
/**
* @param Request $request
* @param bool|array $ignorePlatformReqs
*
* @param bool|string[] $ignorePlatformReqs
* @return void
*/
protected function checkForRootRequireProblems(Request $request, $ignorePlatformReqs)
@ -192,8 +185,7 @@ class Solver
}
/**
* @param Request $request
* @param bool|array $ignorePlatformReqs
* @param bool|string[] $ignorePlatformReqs
* @return LockTransaction
*/
public function solve(Request $request, $ignorePlatformReqs = false)
@ -304,7 +296,6 @@ class Solver
*
* @param int $level
* @param string|int $literal
* @param Rule $rule
* @return int
*/
private function setPropagateLearn($level, $literal, Rule $rule)
@ -332,11 +323,6 @@ class Solver
"Trying to revert to invalid level ".(int) $newLevel." from level ".(int) $level."."
);
}
if (!$newRule) {
throw new SolverBugException(
"No rule was learned from analyzing $rule at level $level."
);
}
$level = $newLevel;
@ -358,8 +344,7 @@ class Solver
/**
* @param int $level
* @param array $decisionQueue
* @param Rule $rule
* @param int[] $decisionQueue
* @return int
*/
private function selectAndInstall($level, array $decisionQueue, Rule $rule)
@ -379,8 +364,7 @@ class Solver
/**
* @param int $level
* @param Rule $rule
* @return array
* @return array{int, int, GenericRule, int}
*/
protected function analyze($level, Rule $rule)
{
@ -527,6 +511,7 @@ class Solver
}
/**
* @param array<string, true> $ruleSeen
* @return void
*/
private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule, array &$ruleSeen)
@ -557,7 +542,6 @@ class Solver
}
/**
* @param Rule $conflictRule
* @return int
*/
private function analyzeUnsolvable(Rule $conflictRule)

@ -17,6 +17,9 @@ namespace Composer\DependencyResolver;
*/
class SolverBugException extends \RuntimeException
{
/**
* @param string $message
*/
public function __construct($message)
{
parent::__construct(

@ -14,7 +14,6 @@ namespace Composer\DependencyResolver;
use Composer\Util\IniHelper;
use Composer\Repository\RepositorySet;
use Composer\Package\PackageInterface;
/**
* @author Nils Adermann <naderman@naderman.de>
@ -29,7 +28,7 @@ class SolverProblemsException extends \RuntimeException
protected $learnedPool;
/**
* @param Problem[] $problems
* @param Problem[] $problems
* @param array<Rule[]> $learnedPool
*/
public function __construct(array $problems, array $learnedPool)
@ -41,6 +40,8 @@ class SolverProblemsException extends \RuntimeException
}
/**
* @param bool $isVerbose
* @param bool $isDevExtraction
* @return string
*/
public function getPrettyString(RepositorySet $repositorySet, Request $request, Pool $pool, $isVerbose, $isDevExtraction = false)
@ -123,6 +124,7 @@ class SolverProblemsException extends \RuntimeException
}
/**
* @param Rule[][] $reasonSets
* @return bool
*/
private function hasExtensionProblems(array $reasonSets)

@ -46,6 +46,10 @@ class Transaction
*/
protected $resultPackagesByName = array();
/**
* @param PackageInterface[] $presentPackages
* @param PackageInterface[] $resultPackages
*/
public function __construct($presentPackages, $resultPackages)
{
$this->presentPackages = $presentPackages;
@ -53,12 +57,18 @@ class Transaction
$this->operations = $this->calculateOperations();
}
/** @return OperationInterface[] */
/**
* @return OperationInterface[]
*/
public function getOperations()
{
return $this->operations;
}
/**
* @param PackageInterface[] $resultPackages
* @return void
*/
private function setResultPackageMaps($resultPackages)
{
$packageSort = function (PackageInterface $a, PackageInterface $b) {
@ -88,6 +98,9 @@ class Transaction
}
}
/**
* @return OperationInterface[]
*/
protected function calculateOperations()
{
$operations = array();
@ -228,6 +241,9 @@ class Transaction
return $roots;
}
/**
* @return PackageInterface[]
*/
protected function getProvidersInResult(Link $link)
{
if (!isset($this->resultPackagesByName[$link->getTarget()])) {

@ -15,7 +15,6 @@ namespace Composer\Plugin;
use Composer\EventDispatcher\Event;
use Composer\Repository\RepositoryInterface;
use Composer\DependencyResolver\Request;
use Composer\Package\PackageInterface;
use Composer\Package\BasePackage;
/**
@ -54,11 +53,11 @@ class PrePoolCreateEvent extends Event
*/
private $rootReferences;
/**
* @var PackageInterface[]
* @var BasePackage[]
*/
private $packages;
/**
* @var PackageInterface[]
* @var BasePackage[]
*/
private $unacceptableFixedPackages;
@ -69,6 +68,8 @@ class PrePoolCreateEvent extends Event
* @param int[] $stabilityFlags array of package name => BasePackage::STABILITY_* value
* @param array[] $rootAliases array of package => version => [alias, alias_normalized]
* @param string[] $rootReferences
* @param BasePackage[] $packages
* @param BasePackage[] $unacceptableFixedPackages
*
* @phpstan-param array<string, BasePackage::STABILITY_*> $acceptableStabilities
* @phpstan-param array<string, BasePackage::STABILITY_*> $stabilityFlags
@ -142,7 +143,7 @@ class PrePoolCreateEvent extends Event
}
/**
* @return PackageInterface[]
* @return BasePackage[]
*/
public function getPackages()
{
@ -150,7 +151,7 @@ class PrePoolCreateEvent extends Event
}
/**
* @return PackageInterface[]
* @return BasePackage[]
*/
public function getUnacceptableFixedPackages()
{
@ -158,7 +159,7 @@ class PrePoolCreateEvent extends Event
}
/**
* @param PackageInterface[] $packages
* @param BasePackage[] $packages
*/
public function setPackages(array $packages)
{
@ -166,7 +167,7 @@ class PrePoolCreateEvent extends Event
}
/**
* @param PackageInterface[] $packages
* @param BasePackage[] $packages
*/
public function setUnacceptableFixedPackages(array $packages)
{

@ -68,6 +68,7 @@ class RuleSetTest extends TestCase
$ruleSet = new RuleSet;
$this->setExpectedException('OutOfBoundsException');
// @phpstan-ignore-next-line
$ruleSet->add(new GenericRule(array(), Rule::RULE_ROOT_REQUIRE, array('packageName' => '', 'constraint' => new MatchAllConstraint)), 7);
}

Loading…
Cancel
Save