Skip to content

Commit c886276

Browse files
authored
Merge pull request #4452 from oleibman/stan1003write
More Phpstan Level 10 Prep - Writers
2 parents fb2cfed + 6620337 commit c886276

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+499
-159
lines changed

phpstan.neon.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,5 @@ parameters:
2828
# Accept a bit anything for assert methods
2929
- '~^Parameter \#2 .* of static method PHPUnit\\Framework\\Assert\:\:assert\w+\(\) expects .*, .* given\.$~'
3030
#- '~Method .*rovider.* return type has no value type specified in iterable type array\.$~'
31+
#- '~Method .*rovider.* should return array but returns mixed\.$~'
3132
- identifier: missingType.iterableValue

src/PhpSpreadsheet/Cell/Coordinate.php

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PhpOffice\PhpSpreadsheet\Cell;
44

55
use PhpOffice\PhpSpreadsheet\Exception;
6+
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
67
use PhpOffice\PhpSpreadsheet\Worksheet\Validations;
78
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
89

@@ -162,7 +163,7 @@ public static function splitRange(string $range): array
162163
/**
163164
* Build range from coordinate strings.
164165
*
165-
* @param array $range Array containing one or more arrays containing one or two coordinate strings
166+
* @param mixed[] $range Array containing one or more arrays containing one or two coordinate strings
166167
*
167168
* @return string String representation of $pRange
168169
*/
@@ -187,7 +188,7 @@ public static function buildRange(array $range): string
187188
*
188189
* @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
189190
*
190-
* @return array Range coordinates [Start Cell, End Cell]
191+
* @return array{array{int, int}, array{int, int}} Range coordinates [Start Cell, End Cell]
191192
* where Start Cell and End Cell are arrays (Column Number, Row Number)
192193
*/
193194
public static function rangeBoundaries(string $range): array
@@ -224,6 +225,8 @@ public static function rangeBoundaries(string $range): array
224225
// Translate column into index
225226
$rangeStart[0] = self::columnIndexFromString($rangeStart[0]);
226227
$rangeEnd[0] = self::columnIndexFromString($rangeEnd[0]);
228+
$rangeStart[1] = (int) $rangeStart[1];
229+
$rangeEnd[1] = (int) $rangeEnd[1];
227230

228231
return [$rangeStart, $rangeEnd];
229232
}
@@ -233,7 +236,7 @@ public static function rangeBoundaries(string $range): array
233236
*
234237
* @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
235238
*
236-
* @return array Range dimension (width, height)
239+
* @return array{int, int} Range dimension (width, height)
237240
*/
238241
public static function rangeDimension(string $range): array
239242
{
@@ -248,7 +251,7 @@ public static function rangeDimension(string $range): array
248251
*
249252
* @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
250253
*
251-
* @return array Range coordinates [Start Cell, End Cell]
254+
* @return array{array{string, int}, array{string, int}} Range coordinates [Start Cell, End Cell]
252255
* where Start Cell and End Cell are arrays [Column ID, Row Number]
253256
*/
254257
public static function getRangeBoundaries(string $range): array
@@ -267,7 +270,7 @@ public static function getRangeBoundaries(string $range): array
267270
*
268271
* @param string $reference Coordinate or Range (e.g. A1:A1, B2, B:C, 2:3)
269272
*
270-
* @return array reference data
273+
* @return array{type: string, firstCoordinate?: string, secondCoordinate?: string, coordinate?: string, worksheet?: string, localReference?: string} reference data
271274
*/
272275
private static function validateReferenceAndGetData($reference): array
273276
{
@@ -331,7 +334,13 @@ public static function coordinateIsInsideRange(string $range, string $coordinate
331334
}
332335
}
333336

337+
if (!isset($rangeData['localReference'])) {
338+
return false;
339+
}
334340
$boundaries = self::rangeBoundaries($rangeData['localReference']);
341+
if (!isset($coordinateData['localReference'])) {
342+
return false;
343+
}
335344
$coordinates = self::indexesFromString($coordinateData['localReference']);
336345

337346
$columnIsInside = $boundaries[0][0] <= $coordinates[0] && $coordinates[0] <= $boundaries[1][0];
@@ -358,6 +367,7 @@ public static function columnIndexFromString(?string $columnAddress): int
358367
// Using a lookup cache adds a slight memory overhead, but boosts speed
359368
// caching using a static within the method is faster than a class static,
360369
// though it's additional memory overhead
370+
/** @var int[] */
361371
static $indexCache = [];
362372
$columnAddress = $columnAddress ?? '';
363373

@@ -367,6 +377,7 @@ public static function columnIndexFromString(?string $columnAddress): int
367377
// It's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array
368378
// rather than use ord() and make it case insensitive to get rid of the strtoupper() as well.
369379
// Because it's a static, there's no significant memory overhead either.
380+
/** @var array<string, int> */
370381
static $columnLookup = [
371382
'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10,
372383
'K' => 11, 'L' => 12, 'M' => 13, 'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19,
@@ -402,23 +413,25 @@ public static function columnIndexFromString(?string $columnAddress): int
402413
);
403414
}
404415

416+
private const LOOKUP_CACHE = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ';
417+
405418
/**
406419
* String from column index.
407420
*
408421
* @param int|numeric-string $columnIndex Column index (A = 1)
409422
*/
410423
public static function stringFromColumnIndex(int|string $columnIndex): string
411424
{
425+
/** @var string[] */
412426
static $indexCache = [];
413-
static $lookupCache = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ';
414427

415428
if (!isset($indexCache[$columnIndex])) {
416429
$indexValue = $columnIndex;
417430
$base26 = '';
418431
do {
419432
$characterValue = ($indexValue % 26) ?: 26;
420433
$indexValue = ($indexValue - $characterValue) / 26;
421-
$base26 = $lookupCache[$characterValue] . $base26;
434+
$base26 = self::LOOKUP_CACHE[$characterValue] . $base26;
422435
} while ($indexValue > 0);
423436
$indexCache[$columnIndex] = $base26;
424437
}
@@ -431,7 +444,7 @@ public static function stringFromColumnIndex(int|string $columnIndex): string
431444
*
432445
* @param string $cellRange Range: e.g. 'A1' or 'A1:C10' or 'A1:E10,A20:E25' or 'A1:E5 C3:G7' or 'A1:C1,A3:C3 B1:C3'
433446
*
434-
* @return array Array containing single cell references
447+
* @return string[] Array containing single cell references
435448
*/
436449
public static function extractAllCellReferencesInRange(string $cellRange): array
437450
{
@@ -452,23 +465,35 @@ public static function extractAllCellReferencesInRange(string $cellRange): array
452465

453466
$cells = [];
454467
foreach ($ranges as $range) {
468+
/** @var string $range */
455469
$cells[] = self::getReferencesForCellBlock($range);
456470
}
457471

472+
/** @var mixed[] */
458473
$cells = self::processRangeSetOperators($operators, $cells);
459474

460475
if (empty($cells)) {
461476
return [];
462477
}
463478

464-
$cellList = array_merge(...$cells);
479+
/** @var string[] */
480+
$cellList = array_merge(...$cells); //* @phpstan-ignore-line
481+
// Unsure how to satisfy phpstan in line above
465482

466-
return array_map(
467-
fn ($cellAddress) => ($worksheet !== '') ? "{$quoted}{$worksheet}{$quoted}!{$cellAddress}" : $cellAddress,
483+
$retVal = array_map(
484+
fn (string $cellAddress) => ($worksheet !== '') ? "{$quoted}{$worksheet}{$quoted}!{$cellAddress}" : $cellAddress,
468485
self::sortCellReferenceArray($cellList)
469486
);
487+
488+
return $retVal;
470489
}
471490

491+
/**
492+
* @param mixed[] $operators
493+
* @param mixed[][] $cells
494+
*
495+
* @return mixed[]
496+
*/
472497
private static function processRangeSetOperators(array $operators, array $cells): array
473498
{
474499
$operatorCount = count($operators);
@@ -489,6 +514,11 @@ private static function processRangeSetOperators(array $operators, array $cells)
489514
return $cells;
490515
}
491516

517+
/**
518+
* @param string[] $cellList
519+
*
520+
* @return string[]
521+
*/
492522
private static function sortCellReferenceArray(array $cellList): array
493523
{
494524
// Sort the result by column and row
@@ -497,6 +527,7 @@ private static function sortCellReferenceArray(array $cellList): array
497527
$column = '';
498528
$row = 0;
499529
sscanf($coordinate, '%[A-Z]%d', $column, $row);
530+
/** @var int $row */
500531
$key = (--$row * 16384) + self::columnIndexFromString((string) $column);
501532
$sortKeys[$key] = $coordinate;
502533
}
@@ -548,7 +579,7 @@ public static function resolveUnionAndIntersection(string $cellBlock, string $im
548579
*
549580
* @param string $cellBlock A cell range e.g. A4:B5
550581
*
551-
* @return array All individual cells in that range
582+
* @return string[] All individual cells in that range
552583
*/
553584
private static function getReferencesForCellBlock(string $cellBlock): array
554585
{
@@ -585,6 +616,8 @@ private static function getReferencesForCellBlock(string $cellBlock): array
585616

586617
// Loop cells
587618
while ($currentColumnIndex < $endColumnIndex) {
619+
/** @var int $currentRow */
620+
/** @var int $endRow */
588621
while ($currentRow <= $endRow) {
589622
$returnValue[] = self::stringFromColumnIndex($currentColumnIndex) . $currentRow;
590623
++$currentRow;
@@ -610,9 +643,9 @@ private static function getReferencesForCellBlock(string $cellBlock): array
610643
*
611644
* [ 'A1:A3' => 'x', 'A4' => 'y' ]
612645
*
613-
* @param array $coordinateCollection associative array mapping coordinates to values
646+
* @param array<string, mixed> $coordinateCollection associative array mapping coordinates to values
614647
*
615-
* @return array associative array mapping coordinate ranges to valuea
648+
* @return array<string, mixed> associative array mapping coordinate ranges to valuea
616649
*/
617650
public static function mergeRangesInCollection(array $coordinateCollection): array
618651
{
@@ -628,7 +661,7 @@ public static function mergeRangesInCollection(array $coordinateCollection): arr
628661

629662
[$column, $row] = self::coordinateFromString($coord);
630663
$row = (int) (ltrim($row, '$'));
631-
$hashCode = $column . '-' . ((is_object($value) && method_exists($value, 'getHashCode')) ? $value->getHashCode() : $value);
664+
$hashCode = $column . '-' . StringHelper::convertToString((is_object($value) && method_exists($value, 'getHashCode')) ? $value->getHashCode() : $value);
632665

633666
if (!isset($hashedValues[$hashCode])) {
634667
$hashedValues[$hashCode] = (object) [
@@ -687,7 +720,7 @@ public static function mergeRangesInCollection(array $coordinateCollection): arr
687720
* Get the individual cell blocks from a range string, removing any $ characters.
688721
* then splitting by operators and returning an array with ranges and operators.
689722
*
690-
* @return array[]
723+
* @return mixed[][]
691724
*/
692725
private static function getCellBlocksFromRangeString(string $rangeString): array
693726
{

src/PhpSpreadsheet/Chart/Chart.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ public function setBottomRightPosition(string $cellAddress = '', ?int $xOffset =
490490
/**
491491
* Get the bottom right position of the chart.
492492
*
493-
* @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
493+
* @return array{cell: string, xOffset: int, yOffset:int} an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
494494
*/
495495
public function getBottomRightPosition(): array
496496
{

src/PhpSpreadsheet/Chart/PlotArea.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class PlotArea
1717
* First is position in %.
1818
* Second is ChartColor.
1919
*
20-
* @var array[]
20+
* @var array<array{float, ChartColor}>
2121
*/
2222
private array $gradientFillStops = [];
2323

@@ -126,6 +126,7 @@ public function getNoFill(): bool
126126
return $this->noFill;
127127
}
128128

129+
/** @param array<array{float, ChartColor}> $gradientFillStops */
129130
public function setGradientFillProperties(array $gradientFillStops, ?float $gradientFillAngle): self
130131
{
131132
$this->gradientFillStops = $gradientFillStops;
@@ -144,6 +145,8 @@ public function getGradientFillAngle(): ?float
144145

145146
/**
146147
* Get gradientFillStops.
148+
*
149+
* @return array<array{float, ChartColor}>
147150
*/
148151
public function getGradientFillStops(): array
149152
{

src/PhpSpreadsheet/Chart/Title.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ public function __construct(array|RichText|string $caption = '', ?Layout $layout
4646

4747
/**
4848
* Get caption.
49+
*
50+
* @return array<RichText|string>|RichText|string
4951
*/
5052
public function getCaption(): array|RichText|string
5153
{

src/PhpSpreadsheet/Reader/BaseReader.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,13 @@ public function setIncludeCharts(bool $includeCharts): self
112112
return $this;
113113
}
114114

115+
/** @return null|string[] */
115116
public function getLoadSheetsOnly(): ?array
116117
{
117118
return $this->loadSheetsOnly;
118119
}
119120

121+
/** @param null|string|string[] $sheetList */
120122
public function setLoadSheetsOnly(string|array|null $sheetList): self
121123
{
122124
if ($sheetList === null) {

src/PhpSpreadsheet/Reader/Csv.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ public function listWorksheetInfo(string $filename): array
228228
$this->checkSeparator();
229229
$this->inferSeparator();
230230

231+
/** @var array<int, array{worksheetName: string, lastColumnLetter: string, lastColumnIndex: int, totalRows: int, totalColumns: int, sheetState: string}> */
231232
$worksheetInfo = [];
232233
$worksheetInfo[0]['worksheetName'] = 'Worksheet';
233234
$worksheetInfo[0]['lastColumnLetter'] = 'A';

src/PhpSpreadsheet/Reader/Csv/Delimiter.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Delimiter
1313

1414
protected string $enclosure;
1515

16+
/** @var array<string, int[]> */
1617
protected array $counts = [];
1718

1819
protected int $numberLines = 0;
@@ -53,6 +54,7 @@ protected function countPotentialDelimiters(): void
5354
}
5455
}
5556

57+
/** @param array<string, int> $delimiterKeys */
5658
protected function countDelimiterValues(string $line, array $delimiterKeys): void
5759
{
5860
$splitString = mb_str_split($line, 1, 'UTF-8');
@@ -69,7 +71,7 @@ public function infer(): ?string
6971
// Calculate the mean square deviations for each delimiter
7072
// (ignoring delimiters that haven't been found consistently)
7173
$meanSquareDeviations = [];
72-
$middleIdx = floor(($this->numberLines - 1) / 2);
74+
$middleIdx = (int) floor(($this->numberLines - 1) / 2);
7375

7476
foreach (self::POTENTIAL_DELIMETERS as $delimiter) {
7577
$series = $this->counts[$delimiter];

src/PhpSpreadsheet/Reader/Gnumeric.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class Gnumeric extends BaseReader
3838

3939
/**
4040
* Shared Expressions.
41+
*
42+
* @var array<array{column: int, row: int, formula:string}>
4143
*/
4244
private array $expressions = [];
4345

@@ -48,6 +50,7 @@ class Gnumeric extends BaseReader
4850

4951
private ReferenceHelper $referenceHelper;
5052

53+
/** @var array{'dataType': string[]} */
5154
public static array $mappings = [
5255
'dataType' => [
5356
'10' => DataType::TYPE_NULL,
@@ -96,6 +99,8 @@ private static function matchXml(XMLReader $xml, string $expectedLocalName): boo
9699

97100
/**
98101
* Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object.
102+
*
103+
* @return string[]
99104
*/
100105
public function listWorksheetNames(string $filename): array
101106
{
@@ -203,6 +208,7 @@ private function gzfileGetContents(string $filename): string
203208
return $data;
204209
}
205210

211+
/** @return mixed[] */
206212
public static function gnumericMappings(): array
207213
{
208214
return array_merge(self::$mappings, Styles::$mappings);
@@ -559,8 +565,8 @@ private function loadCell(
559565
if (((string) $cell) > '') {
560566
// Formula
561567
$this->expressions[$ExprID] = [
562-
'column' => $cellAttributes->Col,
563-
'row' => $cellAttributes->Row,
568+
'column' => (int) $cellAttributes->Col,
569+
'row' => (int) $cellAttributes->Row,
564570
'formula' => (string) $cell,
565571
];
566572
} else {

src/PhpSpreadsheet/Reader/Gnumeric/PageSetup.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ public function sheetMargins(SimpleXMLElement $sheet): self
7070
return $this;
7171
}
7272

73+
/**
74+
* @param float[] $marginSet
75+
*
76+
* @return float[]
77+
*/
7378
private function buildMarginSet(SimpleXMLElement $sheet, array $marginSet): array
7479
{
7580
foreach ($sheet->PrintInformation->Margins->children(Gnumeric::NAMESPACE_GNM) as $key => $margin) {
@@ -83,6 +88,7 @@ private function buildMarginSet(SimpleXMLElement $sheet, array $marginSet): arra
8388
return $marginSet;
8489
}
8590

91+
/** @param float[] $marginSet */
8692
private function adjustMargins(array $marginSet): void
8793
{
8894
foreach ($marginSet as $key => $marginSize) {

0 commit comments

Comments
 (0)