diff --git a/src/Tokenizers/PHP.php b/src/Tokenizers/PHP.php index b914bccddc..ad431869c4 100644 --- a/src/Tokenizers/PHP.php +++ b/src/Tokenizers/PHP.php @@ -1801,9 +1801,9 @@ protected function processAdditional() }//end if continue; - } else if ($this->tokens[$i]['code'] === T_FN) { + } else if ($this->tokens[$i]['code'] === T_FN && isset($this->tokens[($i + 1)]) === true) { // Possible arrow function. - for ($x = ($i + 1); $i < $numTokens; $x++) { + for ($x = ($i + 1); $x < $numTokens; $x++) { if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false && $this->tokens[$x]['code'] !== T_BITWISE_AND ) { @@ -1812,7 +1812,7 @@ protected function processAdditional() } } - if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS) { + if (isset($this->tokens[$x]) === true && $this->tokens[$x]['code'] === T_OPEN_PARENTHESIS) { $ignore = Util\Tokens::$emptyTokens; $ignore += [ T_STRING => T_STRING, diff --git a/tests/Core/Tokenizer/BackfillFnTokenTest.inc b/tests/Core/Tokenizer/BackfillFnTokenTest.inc index 0bff299369..b9bb9751e1 100644 --- a/tests/Core/Tokenizer/BackfillFnTokenTest.inc +++ b/tests/Core/Tokenizer/BackfillFnTokenTest.inc @@ -69,3 +69,7 @@ fn(callable $a) : callable => $a; /* testTernary */ $fn = fn($a) => $a ? /* testTernaryThen */ fn() : string => 'a' : /* testTernaryElse */ fn() : string => 'b'; + +/* testLiveCoding */ +// Intentional parse error. This has to be the last test in the file. +$fn = fn diff --git a/tests/Core/Tokenizer/BackfillFnTokenTest.php b/tests/Core/Tokenizer/BackfillFnTokenTest.php index 4132335680..a14fa86804 100644 --- a/tests/Core/Tokenizer/BackfillFnTokenTest.php +++ b/tests/Core/Tokenizer/BackfillFnTokenTest.php @@ -552,7 +552,31 @@ public function testTernary() /** - * Test that anonymous class tokens without parenthesis do not get assigned a parenthesis owner. + * Test that the backfill presumes T_FN during live coding, but doesn't set the additional index keys. + * + * @covers PHP_CodeSniffer\Tokenizers\PHP::processAdditional + * + * @return void + */ + public function testLiveCoding() + { + $tokens = self::$phpcsFile->getTokens(); + + $token = $this->getTargetToken('/* testLiveCoding */', [T_STRING, T_FN]); + $this->assertSame($tokens[$token]['code'], T_FN, 'Token not tokenized as T_FN'); + + $this->assertArrayNotHasKey('scope_condition', $tokens[$token], 'Scope condition is set'); + $this->assertArrayNotHasKey('scope_opener', $tokens[$token], 'Scope opener is set'); + $this->assertArrayNotHasKey('scope_closer', $tokens[$token], 'Scope closer is set'); + $this->assertArrayNotHasKey('parenthesis_owner', $tokens[$token], 'Parenthesis owner is set'); + $this->assertArrayNotHasKey('parenthesis_opener', $tokens[$token], 'Parenthesis opener is set'); + $this->assertArrayNotHasKey('parenthesis_closer', $tokens[$token], 'Parenthesis closer is set'); + + }//end testLiveCoding() + + + /** + * Helper function to check that all token keys are correctly set for T_FN tokens. * * @param string $token The T_FN token to check. *