Skip to content

Commit 8b96c3f

Browse files
committed
Merge branch 'fix-multiline-array' of https://github.com/grongor/PHP_CodeSniffer
2 parents ff0cb00 + 5fae8d9 commit 8b96c3f

File tree

6 files changed

+178
-79
lines changed

6 files changed

+178
-79
lines changed

src/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php

Lines changed: 70 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,13 @@ public function processSingleLineArray($phpcsFile, $stackPtr, $arrayStart, $arra
243243
if ($fix === true) {
244244
$phpcsFile->fixer->beginChangeset();
245245
$phpcsFile->fixer->addNewline($arrayStart);
246-
$phpcsFile->fixer->addNewlineBefore($arrayEnd);
246+
247+
if ($tokens[($arrayEnd - 1)]['code'] === T_WHITESPACE) {
248+
$phpcsFile->fixer->replaceToken(($arrayEnd - 1), $phpcsFile->eolChar);
249+
} else {
250+
$phpcsFile->fixer->addNewlineBefore($arrayEnd);
251+
}
252+
247253
$phpcsFile->fixer->endChangeset();
248254
}
249255

@@ -394,9 +400,7 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
394400
continue;
395401
}//end if
396402

397-
if ($tokens[$nextToken]['code'] !== T_DOUBLE_ARROW
398-
&& $tokens[$nextToken]['code'] !== T_COMMA
399-
) {
403+
if ($tokens[$nextToken]['code'] !== T_DOUBLE_ARROW && $tokens[$nextToken]['code'] !== T_COMMA) {
400404
continue;
401405
}
402406

@@ -437,7 +441,6 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
437441
&& $tokens[$prev]['code'] !== T_END_NOWDOC)
438442
|| $tokens[($nextToken - 1)]['line'] === $tokens[$nextToken]['line']
439443
) {
440-
$content = $tokens[($nextToken - 2)]['content'];
441444
if ($tokens[($nextToken - 1)]['content'] === $phpcsFile->eolChar) {
442445
$spaceLength = 'newline';
443446
} else {
@@ -607,29 +610,40 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
607610
$phpcsFile->recordMetric($stackPtr, 'Array end comma', 'yes');
608611
}
609612

610-
$lastValueLine = false;
611-
foreach ($indices as $value) {
613+
foreach ($indices as $valuePosition => $value) {
612614
if (empty($value['value']) === true) {
613615
// Array was malformed and we couldn't figure out
614616
// the array value correctly, so we have to ignore it.
615617
// Other parts of this sniff will correct the error.
616618
continue;
617619
}
618620

619-
if ($lastValueLine !== false && $tokens[$value['value']]['line'] === $lastValueLine) {
621+
$valuePointer = $value['value'];
622+
623+
$previous = $phpcsFile->findPrevious([T_WHITESPACE, T_COMMA], ($valuePointer - 1), ($arrayStart + 1), true);
624+
if ($previous === false) {
625+
$previous = $stackPtr;
626+
}
627+
628+
$previousIsWhitespace = $tokens[($valuePointer - 1)]['code'] === T_WHITESPACE;
629+
if ($tokens[$previous]['line'] === $tokens[$valuePointer]['line']) {
620630
$error = 'Each value in a multi-line array must be on a new line';
621-
$fix = $phpcsFile->addFixableError($error, $value['value'], 'ValueNoNewline');
631+
if ($valuePosition === 0) {
632+
$error = 'The first value in a multi-value array must be on a new line';
633+
}
634+
635+
$fix = $phpcsFile->addFixableError($error, $valuePointer, 'ValueNoNewline');
622636
if ($fix === true) {
623-
if ($tokens[($value['value'] - 1)]['code'] === T_WHITESPACE) {
624-
$phpcsFile->fixer->replaceToken(($value['value'] - 1), '');
637+
if ($previousIsWhitespace === true) {
638+
$phpcsFile->fixer->replaceToken(($valuePointer - 1), $phpcsFile->eolChar);
639+
} else {
640+
$phpcsFile->fixer->addNewlineBefore($valuePointer);
625641
}
626-
627-
$phpcsFile->fixer->addNewlineBefore($value['value']);
628642
}
629-
} else if ($tokens[($value['value'] - 1)]['code'] === T_WHITESPACE) {
643+
} else if ($previousIsWhitespace === true) {
630644
$expected = $keywordStart;
631645

632-
$first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $value['value'], true);
646+
$first = $phpcsFile->findFirstOnLine(T_WHITESPACE, $valuePointer, true);
633647
$found = ($tokens[$first]['column'] - 1);
634648
if ($found !== $expected) {
635649
$error = 'Array value not aligned correctly; expected %s spaces but found %s';
@@ -638,18 +652,16 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
638652
$found,
639653
];
640654

641-
$fix = $phpcsFile->addFixableError($error, $value['value'], 'ValueNotAligned', $data);
655+
$fix = $phpcsFile->addFixableError($error, $valuePointer, 'ValueNotAligned', $data);
642656
if ($fix === true) {
643657
if ($found === 0) {
644-
$phpcsFile->fixer->addContent(($value['value'] - 1), str_repeat(' ', $expected));
658+
$phpcsFile->fixer->addContent(($valuePointer - 1), str_repeat(' ', $expected));
645659
} else {
646-
$phpcsFile->fixer->replaceToken(($value['value'] - 1), str_repeat(' ', $expected));
660+
$phpcsFile->fixer->replaceToken(($valuePointer - 1), str_repeat(' ', $expected));
647661
}
648662
}
649663
}
650664
}//end if
651-
652-
$lastValueLine = $tokens[$value['value']]['line'];
653665
}//end foreach
654666
}//end if
655667

@@ -680,82 +692,68 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
680692
to be moved back one space however, then both errors would be fixed.
681693
*/
682694

683-
$numValues = count($indices);
684-
685-
$indicesStart = ($keywordStart + 1);
686-
$indexLine = $tokens[$stackPtr]['line'];
687-
$lastIndexLine = null;
688-
foreach ($indices as $index) {
689-
if ($index['value'] === false) {
695+
$indicesStart = ($keywordStart + 1);
696+
foreach ($indices as $valuePosition => $index) {
697+
$valuePointer = $index['value'];
698+
if ($valuePointer === false) {
690699
// Syntax error or live coding.
691700
continue;
692701
}
693702

694703
if (isset($index['index']) === false) {
695704
// Array value only.
696-
if ($tokens[$index['value']]['line'] === $tokens[$stackPtr]['line'] && $numValues > 1) {
697-
$error = 'The first value in a multi-value array must be on a new line';
698-
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'FirstValueNoNewline');
699-
if ($fix === true) {
700-
$phpcsFile->fixer->addNewlineBefore($index['value']);
701-
}
702-
}
703-
704705
continue;
705706
}
706707

707-
$lastIndexLine = $indexLine;
708-
$indexLine = $tokens[$index['index']]['line'];
709-
710-
if ($indexLine === $tokens[$stackPtr]['line']) {
711-
$error = 'The first index in a multi-value array must be on a new line';
712-
$fix = $phpcsFile->addFixableError($error, $index['index'], 'FirstIndexNoNewline');
713-
if ($fix === true) {
714-
$phpcsFile->fixer->addNewlineBefore($index['index']);
715-
}
708+
$indexPointer = $index['index'];
709+
$indexLine = $tokens[$indexPointer]['line'];
716710

717-
continue;
711+
$previous = $phpcsFile->findPrevious([T_WHITESPACE, T_COMMA], ($indexPointer - 1), ($arrayStart + 1), true);
712+
if ($previous === false) {
713+
$previous = $stackPtr;
718714
}
719715

720-
if ($indexLine === $lastIndexLine) {
716+
if ($tokens[$previous]['line'] === $indexLine) {
721717
$error = 'Each index in a multi-line array must be on a new line';
722-
$fix = $phpcsFile->addFixableError($error, $index['index'], 'IndexNoNewline');
718+
if ($valuePosition === 0) {
719+
$error = 'The first index in a multi-value array must be on a new line';
720+
}
721+
722+
$fix = $phpcsFile->addFixableError($error, $indexPointer, 'IndexNoNewline');
723723
if ($fix === true) {
724-
if ($tokens[($index['index'] - 1)]['code'] === T_WHITESPACE) {
725-
$phpcsFile->fixer->replaceToken(($index['index'] - 1), '');
724+
if ($tokens[($indexPointer - 1)]['code'] === T_WHITESPACE) {
725+
$phpcsFile->fixer->replaceToken(($indexPointer - 1), $phpcsFile->eolChar);
726+
} else {
727+
$phpcsFile->fixer->addNewlineBefore($indexPointer);
726728
}
727-
728-
$phpcsFile->fixer->addNewlineBefore($index['index']);
729729
}
730730

731731
continue;
732732
}
733733

734-
if ($tokens[$index['index']]['column'] !== $indicesStart
735-
&& ($index['index'] - 1) !== $arrayStart
736-
) {
734+
if ($tokens[$indexPointer]['column'] !== $indicesStart && ($indexPointer - 1) !== $arrayStart) {
737735
$expected = ($indicesStart - 1);
738-
$found = ($tokens[$index['index']]['column'] - 1);
736+
$found = ($tokens[$indexPointer]['column'] - 1);
739737
$error = 'Array key not aligned correctly; expected %s spaces but found %s';
740738
$data = [
741739
$expected,
742740
$found,
743741
];
744742

745-
$fix = $phpcsFile->addFixableError($error, $index['index'], 'KeyNotAligned', $data);
743+
$fix = $phpcsFile->addFixableError($error, $indexPointer, 'KeyNotAligned', $data);
746744
if ($fix === true) {
747-
if ($found === 0 || $tokens[($index['index'] - 1)]['code'] !== T_WHITESPACE) {
748-
$phpcsFile->fixer->addContent(($index['index'] - 1), str_repeat(' ', $expected));
745+
if ($found === 0 || $tokens[($indexPointer - 1)]['code'] !== T_WHITESPACE) {
746+
$phpcsFile->fixer->addContent(($indexPointer - 1), str_repeat(' ', $expected));
749747
} else {
750-
$phpcsFile->fixer->replaceToken(($index['index'] - 1), str_repeat(' ', $expected));
748+
$phpcsFile->fixer->replaceToken(($indexPointer - 1), str_repeat(' ', $expected));
751749
}
752750
}
753751
}
754752

755-
$arrowStart = ($tokens[$index['index']]['column'] + $maxLength + 1);
753+
$arrowStart = ($tokens[$indexPointer]['column'] + $maxLength + 1);
756754
if ($tokens[$index['arrow']]['column'] !== $arrowStart) {
757-
$expected = ($arrowStart - ($index['index_length'] + $tokens[$index['index']]['column']));
758-
$found = ($tokens[$index['arrow']]['column'] - ($index['index_length'] + $tokens[$index['index']]['column']));
755+
$expected = ($arrowStart - ($index['index_length'] + $tokens[$indexPointer]['column']));
756+
$found = ($tokens[$index['arrow']]['column'] - ($index['index_length'] + $tokens[$indexPointer]['column']));
759757
$error = 'Array double arrow not aligned correctly; expected %s space(s) but found %s';
760758
$data = [
761759
$expected,
@@ -775,9 +773,9 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
775773
}
776774

777775
$valueStart = ($arrowStart + 3);
778-
if ($tokens[$index['value']]['column'] !== $valueStart) {
776+
if ($tokens[$valuePointer]['column'] !== $valueStart) {
779777
$expected = ($valueStart - ($tokens[$index['arrow']]['length'] + $tokens[$index['arrow']]['column']));
780-
$found = ($tokens[$index['value']]['column'] - ($tokens[$index['arrow']]['length'] + $tokens[$index['arrow']]['column']));
778+
$found = ($tokens[$valuePointer]['column'] - ($tokens[$index['arrow']]['length'] + $tokens[$index['arrow']]['column']));
781779
if ($found < 0) {
782780
$found = 'newline';
783781
}
@@ -791,25 +789,24 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
791789
$fix = $phpcsFile->addFixableError($error, $index['arrow'], 'ValueNotAligned', $data);
792790
if ($fix === true) {
793791
if ($found === 'newline') {
794-
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($index['value'] - 1), null, true);
792+
$prev = $phpcsFile->findPrevious(T_WHITESPACE, ($valuePointer - 1), null, true);
795793
$phpcsFile->fixer->beginChangeset();
796-
for ($i = ($prev + 1); $i < $index['value']; $i++) {
794+
for ($i = ($prev + 1); $i < $valuePointer; $i++) {
797795
$phpcsFile->fixer->replaceToken($i, '');
798796
}
799797

800-
$phpcsFile->fixer->replaceToken(($index['value'] - 1), str_repeat(' ', $expected));
798+
$phpcsFile->fixer->replaceToken(($valuePointer - 1), str_repeat(' ', $expected));
801799
$phpcsFile->fixer->endChangeset();
802800
} else if ($found === 0) {
803-
$phpcsFile->fixer->addContent(($index['value'] - 1), str_repeat(' ', $expected));
801+
$phpcsFile->fixer->addContent(($valuePointer - 1), str_repeat(' ', $expected));
804802
} else {
805-
$phpcsFile->fixer->replaceToken(($index['value'] - 1), str_repeat(' ', $expected));
803+
$phpcsFile->fixer->replaceToken(($valuePointer - 1), str_repeat(' ', $expected));
806804
}
807805
}
808806
}//end if
809807

810808
// Check each line ends in a comma.
811-
$valueStart = $index['value'];
812-
$valueLine = $tokens[$index['value']]['line'];
809+
$valueStart = $valuePointer;
813810
$nextComma = false;
814811

815812
$end = $phpcsFile->findEndOfStatement($valueStart);
@@ -833,11 +830,11 @@ public function processMultiLineArray($phpcsFile, $stackPtr, $arrayStart, $array
833830

834831
if ($nextComma === false || ($tokens[$nextComma]['line'] !== $valueLine)) {
835832
$error = 'Each line in an array declaration must end in a comma';
836-
$fix = $phpcsFile->addFixableError($error, $index['value'], 'NoComma');
833+
$fix = $phpcsFile->addFixableError($error, $valuePointer, 'NoComma');
837834

838835
if ($fix === true) {
839836
// Find the end of the line and put a comma there.
840-
for ($i = ($index['value'] + 1); $i <= $arrayEnd; $i++) {
837+
for ($i = ($valuePointer + 1); $i <= $arrayEnd; $i++) {
841838
if ($tokens[$i]['line'] > $valueLine) {
842839
break;
843840
}

src/Standards/Squiz/Tests/Arrays/ArrayDeclarationUnitTest.1.inc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,18 @@ HERE
394394
,
395395
);
396396

397+
array(
398+
lorem(
399+
1
400+
), 2,
401+
);
402+
403+
array(
404+
1 => lorem(
405+
1
406+
), 2 => 2,
407+
);
408+
397409
$foo = array(
398410
'тип' => 'авто',
399411
'цвет' => 'синий',
@@ -429,6 +441,12 @@ $foo = array(
429441
$foo->fn => 'value',
430442
);
431443

444+
array($a, $b,
445+
$c);
446+
447+
array('a' => $a, 'b' => $b,
448+
'c' => $c);
449+
432450
// Intentional syntax error.
433451
$a = array(
434452
'a' =>

src/Standards/Squiz/Tests/Arrays/ArrayDeclarationUnitTest.1.inc.fixed

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,12 @@ $a = array
370370
// comment
371371
(
372372
'a',
373-
'b',
373+
'b',
374374
);
375375

376376
$a = array /* comment */ (
377377
'a',
378-
'b',
378+
'b',
379379
);
380380

381381
$x = array('a' => false);
@@ -422,6 +422,20 @@ HERE
422422
,
423423
);
424424

425+
array(
426+
lorem(
427+
1
428+
),
429+
2,
430+
);
431+
432+
array(
433+
1 => lorem(
434+
1
435+
),
436+
2 => 2,
437+
);
438+
425439
$foo = array(
426440
'тип' => 'авто',
427441
'цвет' => 'синий',
@@ -457,6 +471,18 @@ $foo = array(
457471
$foo->fn => 'value',
458472
);
459473

474+
array(
475+
$a,
476+
$b,
477+
$c,
478+
);
479+
480+
array(
481+
'a' => $a,
482+
'b' => $b,
483+
'c' => $c,
484+
);
485+
460486
// Intentional syntax error.
461487
$a = array(
462488
'a' =>

0 commit comments

Comments
 (0)