From 27cbb660df79c4874a7205f465312f43d9ecf536 Mon Sep 17 00:00:00 2001 From: Greg Sherwood Date: Thu, 26 Mar 2020 10:32:16 +1100 Subject: [PATCH] Fixed bug #2867 : Incorrect scope matching when arrow function used inside IF condition --- package.xml | 1 + .../InlineControlStructureUnitTest.1.inc | 3 ++ ...InlineControlStructureUnitTest.1.inc.fixed | 3 ++ src/Tokenizers/Tokenizer.php | 32 ++++++++++++++----- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/package.xml b/package.xml index a9293e0887..6671307af0 100644 --- a/package.xml +++ b/package.xml @@ -39,6 +39,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> - Fixed bug #2853 : Undefined variable error when using Info report -- Thanks to Juliette Reinders Folmer for the patch - Fixed bug #2865 : Double arrow tokenized as T_STRING when placed after function named "fn" + - Fixed bug #2867 : Incorrect scope matching when arrow function used inside IF condition - Fixed bug #2868 : phpcs:ignore annotation doesnt work inside a docblock - Fixed bug #2878 : PSR12.Files.FileHeader conflicts with Generic.Files.LineEndings - Fixed bug #2895 : PSR2.Methods.FunctionCallSignature.MultipleArguments false positive with arrow function argument diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc index 422efb7e47..1a6ab6900a 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc @@ -250,3 +250,6 @@ $i = 10; while ($i > 0 && --$i); for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++); + +if ($this->valid(fn(): bool => 2 > 1)) { +} diff --git a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed index a37a109bcd..4cd8ee4d6c 100644 --- a/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed +++ b/src/Standards/Generic/Tests/ControlStructures/InlineControlStructureUnitTest.1.inc.fixed @@ -283,3 +283,6 @@ $i = 10; while ($i > 0 && --$i); for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++); + +if ($this->valid(fn(): bool => 2 > 1)) { +} diff --git a/src/Tokenizers/Tokenizer.php b/src/Tokenizers/Tokenizer.php index 66f7885c81..82b2b9cc78 100644 --- a/src/Tokenizers/Tokenizer.php +++ b/src/Tokenizers/Tokenizer.php @@ -1314,15 +1314,31 @@ private function recurseScopeMap($stackPtr, $depth=1, &$ignore=0) }//end if if ($ignore === 0 || $tokenType !== T_OPEN_CURLY_BRACKET) { - // We found the opening scope token for $currType. - if (PHP_CODESNIFFER_VERBOSITY > 1) { - $type = $this->tokens[$stackPtr]['type']; - echo str_repeat("\t", $depth); - echo "=> Found scope opener for $stackPtr:$type".PHP_EOL; - } + $openerNested = isset($this->tokens[$i]['nested_parenthesis']); + $ownerNested = isset($this->tokens[$stackPtr]['nested_parenthesis']); - $opener = $i; - } + if (($openerNested === true && $ownerNested === false) + || ($openerNested === false && $ownerNested === true) + || ($openerNested === true + && $this->tokens[$i]['nested_parenthesis'] !== $this->tokens[$stackPtr]['nested_parenthesis']) + ) { + // We found the a token that looks like the opener, but it's nested differently. + if (PHP_CODESNIFFER_VERBOSITY > 1) { + $type = $this->tokens[$i]['type']; + echo str_repeat("\t", $depth); + echo "* ignoring possible opener $i:$type as nested parenthesis don't match *".PHP_EOL; + } + } else { + // We found the opening scope token for $currType. + if (PHP_CODESNIFFER_VERBOSITY > 1) { + $type = $this->tokens[$stackPtr]['type']; + echo str_repeat("\t", $depth); + echo "=> Found scope opener for $stackPtr:$type".PHP_EOL; + } + + $opener = $i; + } + }//end if } else if ($tokenType === T_SEMICOLON && $opener === null && (isset($this->tokens[$stackPtr]['parenthesis_closer']) === false