From 9e1378d806e7089d0a0e363aed4bf91769ae577b Mon Sep 17 00:00:00 2001 From: oleibman <10341515+oleibman@users.noreply.github.com> Date: Thu, 16 Feb 2023 19:18:02 -0800 Subject: [PATCH] Resolve Phpstan Messages - Statistical/Trend and Shared/Trend (#3362) * Resolve Phpstan Messages - Statistical/Trend and Shared/Trend Reduce number of Phpstan messages by addressing their issues. The changes in this PR are all to doc blocks; no executable code is changed. * Scrutinizer 1 mystifying "new" error (matches "old" error), 2 updated doc blocks. --- phpstan-baseline.neon | 185 ------------------ .../Calculation/Statistical/Trends.php | 8 +- src/PhpSpreadsheet/Shared/Trend/BestFit.php | 27 +++ .../Shared/Trend/PolynomialBestFit.php | 8 + src/PhpSpreadsheet/Shared/Trend/Trend.php | 11 +- 5 files changed, 51 insertions(+), 188 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index eb3eae5ac..e5cc736f1 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -25,26 +25,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/FormulaParser.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:GROWTH\\(\\) should return array\\ but returns array\\\\>\\>\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:TREND\\(\\) should return array\\ but returns array\\\\>\\>\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array1 with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array2 with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - message: "#^Cannot access offset 1 on array\\|false\\.$#" count: 1 @@ -220,171 +200,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/OLERead.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$const with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$meanX with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$meanY with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumX with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumX2 with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumXY with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumY with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumY2 with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:getBestFitType\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:getError\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:sumSquares\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$DFResiduals has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$SSRegression has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$SSResiduals has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$correlation has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$covariance has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$f has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$goodnessOfFit has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$intersect has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$intersectSE has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$slope has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$slopeSE has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$stdevOfResiduals has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$xOffset has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$yOffset has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/BestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\PolynomialBestFit\\:\\:getCoefficients\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\PolynomialBestFit\\:\\:getCoefficients\\(\\) has parameter \\$dp with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php - - - - message: "#^Call to an undefined method object\\:\\:getGoodnessOfFit\\(\\)\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$const with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$trendType with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$xValues with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$yValues with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/Trend/Trend.php - - message: "#^Cannot access offset 'comp' on array\\|false\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php index af73519ef..705de17d8 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php @@ -21,6 +21,10 @@ class Trends } } + /** + * @param mixed $array1 should be array, but scalar is made into one + * @param mixed $array2 should be array, but scalar is made into one + */ private static function checkTrendArrays(&$array1, &$array2): void { if (!is_array($array1)) { @@ -168,7 +172,7 @@ class Trends $returnArray[0][] = [$bestFitExponential->getValueOfYForX($xValue)]; } - return $returnArray; + return $returnArray; //* @phpstan-ignore-line } /** @@ -425,6 +429,6 @@ class Trends $returnArray[0][] = [$bestFitLinear->getValueOfYForX($xValue)]; } - return $returnArray; + return $returnArray; //* @phpstan-ignore-line } } diff --git a/src/PhpSpreadsheet/Shared/Trend/BestFit.php b/src/PhpSpreadsheet/Shared/Trend/BestFit.php index b2b0d9440..a8d7c93b7 100644 --- a/src/PhpSpreadsheet/Shared/Trend/BestFit.php +++ b/src/PhpSpreadsheet/Shared/Trend/BestFit.php @@ -53,39 +53,55 @@ abstract class BestFit */ protected $yBestFitValues = []; + /** @var float */ protected $goodnessOfFit = 1; + /** @var float */ protected $stdevOfResiduals = 0; + /** @var float */ protected $covariance = 0; + /** @var float */ protected $correlation = 0; + /** @var float */ protected $SSRegression = 0; + /** @var float */ protected $SSResiduals = 0; + /** @var float */ protected $DFResiduals = 0; + /** @var float */ protected $f = 0; + /** @var float */ protected $slope = 0; + /** @var float */ protected $slopeSE = 0; + /** @var float */ protected $intersect = 0; + /** @var float */ protected $intersectSE = 0; + /** @var float */ protected $xOffset = 0; + /** @var float */ protected $yOffset = 0; + /** @return bool */ public function getError() { return $this->error; } + /** @return string */ public function getBestFitType() { return $this->bestFitType; @@ -344,6 +360,16 @@ abstract class BestFit return $x == $y; } + /** + * @param float $sumX + * @param float $sumY + * @param float $sumX2 + * @param float $sumY2 + * @param float $sumXY + * @param float $meanX + * @param float $meanY + * @param bool|int $const + */ protected function calculateGoodnessOfFit($sumX, $sumY, $sumX2, $sumY2, $sumXY, $meanX, $meanY, $const): void { $SSres = $SScov = $SStot = $SSsex = 0.0; @@ -399,6 +425,7 @@ abstract class BestFit } } + /** @return float|int */ private function sumSquares(array $values) { return array_sum( diff --git a/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php b/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php index a21635966..222a42300 100644 --- a/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php +++ b/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php @@ -108,6 +108,7 @@ class PolynomialBestFit extends BestFit if ($dp != 0) { $coefficients = []; // Scrutinizer is correct - $this->slope is float, not array. + //* @phpstan-ignore-next-line foreach ($this->slope as $coefficient) { $coefficients[] = round($coefficient, $dp); } @@ -119,6 +120,11 @@ class PolynomialBestFit extends BestFit return $this->slope; } + /** + * @param int $dp + * + * @return array + */ public function getCoefficients($dp = 0) { // Phpstan and Scrutinizer are both correct - getSlope returns float, not array. @@ -176,6 +182,8 @@ class PolynomialBestFit extends BestFit } $this->intersect = array_shift($coefficients); + // Phpstan (and maybe Scrutinizer) are correct + //* @phpstan-ignore-next-line $this->slope = $coefficients; $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, 0, 0, 0); diff --git a/src/PhpSpreadsheet/Shared/Trend/Trend.php b/src/PhpSpreadsheet/Shared/Trend/Trend.php index 929f59b9c..b94609af7 100644 --- a/src/PhpSpreadsheet/Shared/Trend/Trend.php +++ b/src/PhpSpreadsheet/Shared/Trend/Trend.php @@ -48,6 +48,14 @@ class Trend */ private static $trendCache = []; + /** + * @param string $trendType + * @param array $yValues + * @param array $xValues + * @param bool $const + * + * @return mixed + */ public static function calculate($trendType = self::TREND_BEST_FIT, $yValues = [], $xValues = [], $const = true) { // Calculate number of points in each dataset @@ -72,7 +80,6 @@ class Trend case self::TREND_POWER: if (!isset(self::$trendCache[$key])) { $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; - // @phpstan-ignore-next-line self::$trendCache[$key] = new $className($yValues, $xValues, $const); } @@ -96,7 +103,9 @@ class Trend $bestFitValue = []; foreach (self::$trendTypes as $trendMethod) { $className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit'; + //* @phpstan-ignore-next-line $bestFit[$trendMethod] = new $className($yValues, $xValues, $const); + //* @phpstan-ignore-next-line $bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit(); } if ($trendType != self::TREND_BEST_FIT_NO_POLY) {