From 245f79f9e5f0b0a884c3aad772a5679045c962af Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Fri, 22 Jul 2022 18:32:42 -0400 Subject: [PATCH 01/11] Fix some minor type errors and improve code comments --- VariableAnalysis/Lib/Helpers.php | 2 +- .../CodeAnalysis/VariableAnalysisSniff.php | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/VariableAnalysis/Lib/Helpers.php b/VariableAnalysis/Lib/Helpers.php index 76fe005..e831000 100644 --- a/VariableAnalysis/Lib/Helpers.php +++ b/VariableAnalysis/Lib/Helpers.php @@ -889,7 +889,7 @@ public static function isIndexInsideScope($needle, $scopeStart, $scopeEnd) * @param File $phpcsFile * @param int $scopeStartIndex * - * @return int + * @return int|null */ public static function getScopeCloseForScopeOpen(File $phpcsFile, $scopeStartIndex) { diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 3125663..02b6ab1 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -38,9 +38,6 @@ class VariableAnalysisSniff implements Sniff * Each array of scopes is keyed by a string containing the filename (see * `getFilename`). * - * Unlike the `ScopeInfo` objects stored in `$this->scopes`, these objects do - * not track variables themselves, only the position of the scope boundaries. - * * @var array */ private $scopeStartEndPairs = []; @@ -246,8 +243,13 @@ public function process(File $phpcsFile, $stackPtr) $this->recordScopeStartAndEnd($phpcsFile, 0); } +<<<<<<< HEAD // Report variables defined but not used in the current scope as unused // variables if the current token closes scopes. +======= + // Report variables defined in the current scope but not used as unused + // variables if the current token closes a scope. +>>>>>>> 766adf5 (Fix some minor type errors and improve code comments) $this->searchForAndProcessClosingScopesAt($phpcsFile, $stackPtr); // Find and process variables to perform two jobs: to record variable @@ -298,6 +300,9 @@ public function process(File $phpcsFile, $stackPtr) private function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) { $scopeEndIndex = Helpers::getScopeCloseForScopeOpen($phpcsFile, $scopeStartIndex); + if (is_null($scopeEndIndex)) { + return; + } $filename = $this->getFilename(); if (! isset($this->scopeStartEndPairs[$filename])) { $this->scopeStartEndPairs[$filename] = []; @@ -348,7 +353,13 @@ function ($found, $scope) use ($stackPtr) { /** * Find scopes closed by a token and process their variables. * +<<<<<<< HEAD * Calls `processScopeClose()` for each closed scope. +======= + * Calls `processScopeClose()` for each closed scope. Requires that + * `scopeEndIndexCache` has been populated for the current file by + * `recordScopeStartAndEnd()`. +>>>>>>> 766adf5 (Fix some minor type errors and improve code comments) * * @param File $phpcsFile * @param int $stackPtr From a12846f8fe990ccaf52ef6526f23f01e9be50b0a Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Fri, 22 Jul 2022 19:15:31 -0400 Subject: [PATCH 02/11] Remove unnecessary scopeEndIndexCache --- .../CodeAnalysis/VariableAnalysisSniff.php | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 02b6ab1..7695f12 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -42,13 +42,6 @@ class VariableAnalysisSniff implements Sniff */ private $scopeStartEndPairs = []; - /** - * A cache of scope end indices in the current file to improve performance. - * - * @var int[] - */ - private $scopeEndIndexCache = []; - /** * A list of custom functions which pass in variables to be initialized by * reference (eg `preg_match()`) and therefore should not require those @@ -234,8 +227,6 @@ public function process(File $phpcsFile, $stackPtr) // easily accessed in other places which aren't passed the object. if ($this->currentFile !== $phpcsFile) { $this->currentFile = $phpcsFile; - // Reset the scope end cache when the File changes since it is per-file. - $this->scopeEndIndexCache = []; } // Add the global scope for the current file to our scope indexes. @@ -309,7 +300,27 @@ private function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) } Helpers::debug('recording scope for file', $filename, 'start/end', $scopeStartIndex, $scopeEndIndex); $this->scopeStartEndPairs[$filename][] = new ScopeInfo($scopeStartIndex, $scopeEndIndex); - $this->scopeEndIndexCache[] = $scopeEndIndex; + } + + /** + * Find scope close indexes for a file. + * + * @param File $phpcsFile + * + * @return int[] + */ + private function getScopeCloseIndexes($phpcsFile) { + $filename = $phpcsFile->getFilename(); + if (empty($this->scopeStartEndPairs[$filename])) { + return []; + } + $indexes = []; + foreach($this->scopeStartEndPairs[$filename] as $scopeInfo) { + if ($scopeInfo->scopeEndIndex) { + $indexes[] = $scopeInfo->scopeEndIndex; + } + } + return array_unique($indexes); } /** @@ -322,7 +333,8 @@ private function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) */ private function getScopesClosedBy($phpcsFile, $stackPtr) { - if (! in_array($stackPtr, $this->scopeEndIndexCache, true)) { + $scopeEndIndexes = $this->getScopeCloseIndexes($phpcsFile); + if (! in_array($stackPtr, $scopeEndIndexes, true)) { return []; } $scopePairsForFile = isset($this->scopeStartEndPairs[$this->getFilename()]) ? $this->scopeStartEndPairs[$this->getFilename()] : []; @@ -357,7 +369,7 @@ function ($found, $scope) use ($stackPtr) { * Calls `processScopeClose()` for each closed scope. ======= * Calls `processScopeClose()` for each closed scope. Requires that - * `scopeEndIndexCache` has been populated for the current file by + * `scopeStartEndPairs` has been populated for the current file by * `recordScopeStartAndEnd()`. >>>>>>> 766adf5 (Fix some minor type errors and improve code comments) * From 07a02ec343d402c6c4e31e281f477e131ad97a97 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 16:42:17 -0400 Subject: [PATCH 03/11] Add more function comments --- .../Sniffs/CodeAnalysis/VariableAnalysisSniff.php | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 7695f12..1597071 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -234,13 +234,8 @@ public function process(File $phpcsFile, $stackPtr) $this->recordScopeStartAndEnd($phpcsFile, 0); } -<<<<<<< HEAD // Report variables defined but not used in the current scope as unused // variables if the current token closes scopes. -======= - // Report variables defined in the current scope but not used as unused - // variables if the current token closes a scope. ->>>>>>> 766adf5 (Fix some minor type errors and improve code comments) $this->searchForAndProcessClosingScopesAt($phpcsFile, $stackPtr); // Find and process variables to perform two jobs: to record variable @@ -365,13 +360,7 @@ function ($found, $scope) use ($stackPtr) { /** * Find scopes closed by a token and process their variables. * -<<<<<<< HEAD * Calls `processScopeClose()` for each closed scope. -======= - * Calls `processScopeClose()` for each closed scope. Requires that - * `scopeStartEndPairs` has been populated for the current file by - * `recordScopeStartAndEnd()`. ->>>>>>> 766adf5 (Fix some minor type errors and improve code comments) * * @param File $phpcsFile * @param int $stackPtr From 0e35350581bb7a64ba9a79f7974ce69fb087d886 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 16:49:34 -0400 Subject: [PATCH 04/11] If no scope closer is found, use the end of the file --- VariableAnalysis/Lib/Helpers.php | 2 +- VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/VariableAnalysis/Lib/Helpers.php b/VariableAnalysis/Lib/Helpers.php index e831000..76fe005 100644 --- a/VariableAnalysis/Lib/Helpers.php +++ b/VariableAnalysis/Lib/Helpers.php @@ -889,7 +889,7 @@ public static function isIndexInsideScope($needle, $scopeStart, $scopeEnd) * @param File $phpcsFile * @param int $scopeStartIndex * - * @return int|null + * @return int */ public static function getScopeCloseForScopeOpen(File $phpcsFile, $scopeStartIndex) { diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 1597071..b40baed 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -286,9 +286,6 @@ public function process(File $phpcsFile, $stackPtr) private function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) { $scopeEndIndex = Helpers::getScopeCloseForScopeOpen($phpcsFile, $scopeStartIndex); - if (is_null($scopeEndIndex)) { - return; - } $filename = $this->getFilename(); if (! isset($this->scopeStartEndPairs[$filename])) { $this->scopeStartEndPairs[$filename] = []; From 1e6329ee923dbd3967e54a7885ef090de8ea215f Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 18:50:43 -0400 Subject: [PATCH 05/11] Add ScopeManager --- VariableAnalysis/Lib/ScopeManager.php | 60 +++++++++++++++++++ .../CodeAnalysis/VariableAnalysisSniff.php | 49 +++++---------- 2 files changed, 74 insertions(+), 35 deletions(-) create mode 100644 VariableAnalysis/Lib/ScopeManager.php diff --git a/VariableAnalysis/Lib/ScopeManager.php b/VariableAnalysis/Lib/ScopeManager.php new file mode 100644 index 0000000..f7c89de --- /dev/null +++ b/VariableAnalysis/Lib/ScopeManager.php @@ -0,0 +1,60 @@ + + */ + private $scopeStartEndPairs = []; + + /** + * Add a scope's start and end index to our record for the file. + * + * @param File $phpcsFile + * @param int $scopeStartIndex + * + * @return void + */ + public function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) + { + $scopeEndIndex = Helpers::getScopeCloseForScopeOpen($phpcsFile, $scopeStartIndex); + $filename = $phpcsFile->getFilename(); + if (! isset($this->scopeStartEndPairs[$filename])) { + $this->scopeStartEndPairs[$filename] = []; + } + Helpers::debug('recording scope for file', $filename, 'start/end', $scopeStartIndex, $scopeEndIndex); + $this->scopeStartEndPairs[$filename][] = new ScopeInfo($scopeStartIndex, $scopeEndIndex); + } + + /** + * Return the scopes for a file. + * + * @param string $filename + * + * @return ScopeInfo[] + */ + public function getScopesForFilename($filename) + { + if (empty($this->scopeStartEndPairs[$filename])) { + return []; + } + return $this->scopeStartEndPairs[$filename]; + } +} diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index b40baed..9e7229c 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -7,6 +7,7 @@ use VariableAnalysis\Lib\VariableInfo; use VariableAnalysis\Lib\Constants; use VariableAnalysis\Lib\Helpers; +use VariableAnalysis\Lib\ScopeManager; use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; @@ -32,15 +33,9 @@ class VariableAnalysisSniff implements Sniff private $scopes = []; /** - * An associative array of a list of token index pairs which start and end - * scopes and will be used to check for unused variables. - * - * Each array of scopes is keyed by a string containing the filename (see - * `getFilename`). - * - * @var array + * @var ScopeManager */ - private $scopeStartEndPairs = []; + private $scopeManager; /** * A list of custom functions which pass in variables to be initialized by @@ -155,6 +150,11 @@ class VariableAnalysisSniff implements Sniff */ public $allowUnusedVariablesBeforeRequire = false; + public function __construct() + { + $this->scopeManager = new ScopeManager(); + } + /** * Decide which tokens to scan. * @@ -230,8 +230,8 @@ public function process(File $phpcsFile, $stackPtr) } // Add the global scope for the current file to our scope indexes. - if (empty($this->scopeStartEndPairs[$this->getFilename()])) { - $this->recordScopeStartAndEnd($phpcsFile, 0); + if (empty($this->scopeManager->getScopesForFilename($phpcsFile->getFilename()))) { + $this->scopeManager->recordScopeStartAndEnd($phpcsFile, 0); } // Report variables defined but not used in the current scope as unused @@ -270,30 +270,11 @@ public function process(File $phpcsFile, $stackPtr) Helpers::isArrowFunction($phpcsFile, $stackPtr) ) { Helpers::debug('found scope condition', $token); - $this->recordScopeStartAndEnd($phpcsFile, $stackPtr); + $this->scopeManager->recordScopeStartAndEnd($phpcsFile, $stackPtr); return; } } - /** - * Add a scope's start and end index to our record for the file. - * - * @param File $phpcsFile - * @param int $scopeStartIndex - * - * @return void - */ - private function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) - { - $scopeEndIndex = Helpers::getScopeCloseForScopeOpen($phpcsFile, $scopeStartIndex); - $filename = $this->getFilename(); - if (! isset($this->scopeStartEndPairs[$filename])) { - $this->scopeStartEndPairs[$filename] = []; - } - Helpers::debug('recording scope for file', $filename, 'start/end', $scopeStartIndex, $scopeEndIndex); - $this->scopeStartEndPairs[$filename][] = new ScopeInfo($scopeStartIndex, $scopeEndIndex); - } - /** * Find scope close indexes for a file. * @@ -303,11 +284,8 @@ private function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) */ private function getScopeCloseIndexes($phpcsFile) { $filename = $phpcsFile->getFilename(); - if (empty($this->scopeStartEndPairs[$filename])) { - return []; - } $indexes = []; - foreach($this->scopeStartEndPairs[$filename] as $scopeInfo) { + foreach($this->scopeManager->getScopesForFilename($filename) as $scopeInfo) { if ($scopeInfo->scopeEndIndex) { $indexes[] = $scopeInfo->scopeEndIndex; } @@ -329,7 +307,8 @@ private function getScopesClosedBy($phpcsFile, $stackPtr) if (! in_array($stackPtr, $scopeEndIndexes, true)) { return []; } - $scopePairsForFile = isset($this->scopeStartEndPairs[$this->getFilename()]) ? $this->scopeStartEndPairs[$this->getFilename()] : []; + $filename = $phpcsFile->getFilename(); + $scopePairsForFile = $this->scopeManager->getScopesForFilename($filename); $scopeIndicesThisCloses = array_reduce( $scopePairsForFile, /** From f1cf71ee1f0e62ec88155c8aac490f816b98a0d7 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 19:09:40 -0400 Subject: [PATCH 06/11] Improve index of ScopeManager using scopeStart --- VariableAnalysis/Lib/ScopeManager.php | 38 ++++++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/VariableAnalysis/Lib/ScopeManager.php b/VariableAnalysis/Lib/ScopeManager.php index f7c89de..2802984 100644 --- a/VariableAnalysis/Lib/ScopeManager.php +++ b/VariableAnalysis/Lib/ScopeManager.php @@ -17,12 +17,12 @@ class ScopeManager { * An associative array of a list of token index pairs which start and end * scopes and will be used to check for unused variables. * - * Each array of scopes is keyed by a string containing the filename (see - * `getFilename`). + * The outer array of scopes is keyed by a string containing the filename. + * The inner array of scopes in keyed by the scope start token index. * - * @var array + * @var array> */ - private $scopeStartEndPairs = []; + private $scopes = []; /** * Add a scope's start and end index to our record for the file. @@ -30,17 +30,19 @@ class ScopeManager { * @param File $phpcsFile * @param int $scopeStartIndex * - * @return void + * @return ScopeInfo */ public function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) { $scopeEndIndex = Helpers::getScopeCloseForScopeOpen($phpcsFile, $scopeStartIndex); $filename = $phpcsFile->getFilename(); - if (! isset($this->scopeStartEndPairs[$filename])) { - $this->scopeStartEndPairs[$filename] = []; + if (! isset($this->scopes[$filename])) { + $this->scopes[$filename] = []; } Helpers::debug('recording scope for file', $filename, 'start/end', $scopeStartIndex, $scopeEndIndex); - $this->scopeStartEndPairs[$filename][] = new ScopeInfo($scopeStartIndex, $scopeEndIndex); + $scope = new ScopeInfo($scopeStartIndex, $scopeEndIndex); + $this->scopes[$filename][$scopeStartIndex] = $scope; + return $scope; } /** @@ -52,9 +54,25 @@ public function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) */ public function getScopesForFilename($filename) { - if (empty($this->scopeStartEndPairs[$filename])) { + if (empty($this->scopes[$filename])) { return []; } - return $this->scopeStartEndPairs[$filename]; + return array_values($this->scopes[$filename]); + } + + /** + * Return the scope for a scope start index. + * + * @param string $filename + * @param int $scopeStartIndex + * + * @return ScopeInfo|null + */ + public function getScopeForScopeStart($filename, $scopeStartIndex) + { + if (empty($this->scopes[$filename][$scopeStartIndex])) { + return null; + } + return $this->scopes[$filename][$scopeStartIndex]; } } From b8a14508978037ecbb9db4eaf698592937968a5a Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 19:10:06 -0400 Subject: [PATCH 07/11] Replace scope list with ScopeManager --- .../CodeAnalysis/VariableAnalysisSniff.php | 47 ++++--------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 9e7229c..75197ea 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -21,17 +21,6 @@ class VariableAnalysisSniff implements Sniff */ protected $currentFile = null; - /** - * An associative array of scopes for variables encountered so far and the - * variables within them. - * - * Each scope is keyed by a string of the form `filename:scopeStartIndex` - * (see `getScopeKey`). - * - * @var array - */ - private $scopes = []; - /** * @var ScopeManager */ @@ -376,16 +365,6 @@ protected function isGetDefinedVars(File $phpcsFile, $stackPtr) return true; } - /** - * @param int $currScope - * - * @return string - */ - protected function getScopeKey($currScope) - { - return $this->getFilename() . ':' . $currScope; - } - /** * @return string */ @@ -394,17 +373,6 @@ protected function getFilename() return $this->currentFile ? $this->currentFile->getFilename() : 'unknown file'; } - /** - * @param int $currScope - * - * @return ScopeInfo|null - */ - protected function getScopeInfo($currScope) - { - $scopeKey = $this->getScopeKey($currScope); - return isset($this->scopes[$scopeKey]) ? $this->scopes[$scopeKey] : null; - } - /** * @param int $currScope * @@ -412,11 +380,14 @@ protected function getScopeInfo($currScope) */ protected function getOrCreateScopeInfo($currScope) { - $scopeKey = $this->getScopeKey($currScope); - if (!isset($this->scopes[$scopeKey])) { - $this->scopes[$scopeKey] = new ScopeInfo($currScope); + $scope = $this->scopeManager->getScopeForScopeStart($this->getFilename(), $currScope); + if (! $scope) { + if (! $this->currentFile) { + throw new \Exception('Cannot create scope info; current file is not set.'); + } + $scope = $this->scopeManager->recordScopeStartAndEnd($this->currentFile, $currScope); } - return $this->scopes[$scopeKey]; + return $scope; } /** @@ -427,7 +398,7 @@ protected function getOrCreateScopeInfo($currScope) */ protected function getVariableInfo($varName, $currScope) { - $scopeInfo = $this->getScopeInfo($currScope); + $scopeInfo = $this->scopeManager->getScopeForScopeStart($this->getFilename(), $currScope); return ($scopeInfo && isset($scopeInfo->variables[$varName])) ? $scopeInfo->variables[$varName] : null; } @@ -1861,7 +1832,7 @@ protected function processCompact(File $phpcsFile, $stackPtr) */ protected function processScopeClose(File $phpcsFile, $stackPtr) { - $scopeInfo = $this->getScopeInfo($stackPtr); + $scopeInfo = $this->scopeManager->getScopeForScopeStart($phpcsFile->getFilename(), $stackPtr); if (is_null($scopeInfo)) { return; } From 1e8104efe796af9f3cebb03c3fbb94afb9a478a5 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 19:18:34 -0400 Subject: [PATCH 08/11] Move getScopesClosedBy to ScopeManager --- VariableAnalysis/Lib/ScopeManager.php | 36 +++++++++++ .../CodeAnalysis/VariableAnalysisSniff.php | 60 +------------------ 2 files changed, 37 insertions(+), 59 deletions(-) diff --git a/VariableAnalysis/Lib/ScopeManager.php b/VariableAnalysis/Lib/ScopeManager.php index 2802984..d86e6a6 100644 --- a/VariableAnalysis/Lib/ScopeManager.php +++ b/VariableAnalysis/Lib/ScopeManager.php @@ -75,4 +75,40 @@ public function getScopeForScopeStart($filename, $scopeStartIndex) } return $this->scopes[$filename][$scopeStartIndex]; } + + /** + * Find scopes closed by a scope close index. + * + * @param string $filename + * @param int $scopeEndIndex + * + * @return ScopeInfo[] + */ + public function getScopesForScopeEnd($filename, $scopeEndIndex) + { + $scopePairsForFile = $this->getScopesForFilename($filename); + $scopeIndicesThisCloses = array_reduce( + $scopePairsForFile, + /** + * @param ScopeInfo[] $found + * @param ScopeInfo $scope + * + * @return ScopeInfo[] + */ + function ($found, $scope) use ($scopeEndIndex) { + if (! is_int($scope->scopeEndIndex)) { + Helpers::debug('No scope closer found for scope start', $scope->scopeStartIndex); + return $found; + } + + if ($scopeEndIndex === $scope->scopeEndIndex) { + $found[] = $scope; + } + return $found; + }, + [] + ); + return $scopeIndicesThisCloses; + } + } diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 75197ea..200e3c0 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -264,64 +264,6 @@ public function process(File $phpcsFile, $stackPtr) } } - /** - * Find scope close indexes for a file. - * - * @param File $phpcsFile - * - * @return int[] - */ - private function getScopeCloseIndexes($phpcsFile) { - $filename = $phpcsFile->getFilename(); - $indexes = []; - foreach($this->scopeManager->getScopesForFilename($filename) as $scopeInfo) { - if ($scopeInfo->scopeEndIndex) { - $indexes[] = $scopeInfo->scopeEndIndex; - } - } - return array_unique($indexes); - } - - /** - * Find scopes closed by a token. - * - * @param File $phpcsFile - * @param int $stackPtr - * - * @return ScopeInfo[] - */ - private function getScopesClosedBy($phpcsFile, $stackPtr) - { - $scopeEndIndexes = $this->getScopeCloseIndexes($phpcsFile); - if (! in_array($stackPtr, $scopeEndIndexes, true)) { - return []; - } - $filename = $phpcsFile->getFilename(); - $scopePairsForFile = $this->scopeManager->getScopesForFilename($filename); - $scopeIndicesThisCloses = array_reduce( - $scopePairsForFile, - /** - * @param ScopeInfo[] $found - * @param ScopeInfo $scope - * - * @return ScopeInfo[] - */ - function ($found, $scope) use ($stackPtr) { - if (! is_int($scope->scopeEndIndex)) { - Helpers::debug('No scope closer found for scope start', $scope->scopeStartIndex); - return $found; - } - - if ($stackPtr === $scope->scopeEndIndex) { - $found[] = $scope; - } - return $found; - }, - [] - ); - return $scopeIndicesThisCloses; - } - /** * Find scopes closed by a token and process their variables. * @@ -334,7 +276,7 @@ function ($found, $scope) use ($stackPtr) { */ private function searchForAndProcessClosingScopesAt($phpcsFile, $stackPtr) { - $scopeIndicesThisCloses = $this->getScopesClosedBy($phpcsFile, $stackPtr); + $scopeIndicesThisCloses = $this->scopeManager->getScopesForScopeEnd($phpcsFile->getFilename(), $stackPtr); foreach ($scopeIndicesThisCloses as $scopeIndexThisCloses) { Helpers::debug('found closing scope at index', $stackPtr, 'for scopes starting at:', $scopeIndexThisCloses); From a347c26aa5dbdf485245cdbabbbcfb2f13a97d72 Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 19:29:40 -0400 Subject: [PATCH 09/11] Linting fixes --- VariableAnalysis/Lib/ScopeManager.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/VariableAnalysis/Lib/ScopeManager.php b/VariableAnalysis/Lib/ScopeManager.php index d86e6a6..5b0e261 100644 --- a/VariableAnalysis/Lib/ScopeManager.php +++ b/VariableAnalysis/Lib/ScopeManager.php @@ -11,8 +11,8 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -class ScopeManager { - +class ScopeManager +{ /** * An associative array of a list of token index pairs which start and end * scopes and will be used to check for unused variables. @@ -48,7 +48,7 @@ public function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) /** * Return the scopes for a file. * - * @param string $filename + * @param string $filename * * @return ScopeInfo[] */ @@ -63,8 +63,8 @@ public function getScopesForFilename($filename) /** * Return the scope for a scope start index. * - * @param string $filename - * @param int $scopeStartIndex + * @param string $filename + * @param int $scopeStartIndex * * @return ScopeInfo|null */ @@ -79,8 +79,8 @@ public function getScopeForScopeStart($filename, $scopeStartIndex) /** * Find scopes closed by a scope close index. * - * @param string $filename - * @param int $scopeEndIndex + * @param string $filename + * @param int $scopeEndIndex * * @return ScopeInfo[] */ @@ -110,5 +110,4 @@ function ($found, $scope) use ($scopeEndIndex) { ); return $scopeIndicesThisCloses; } - } From 9600ddb8fd0f95539678a1e7af396c89c4c1189c Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 23:05:19 -0400 Subject: [PATCH 10/11] Support php 5.5 by not passing expression to empty) --- VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 200e3c0..6b5e2e5 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -219,7 +219,8 @@ public function process(File $phpcsFile, $stackPtr) } // Add the global scope for the current file to our scope indexes. - if (empty($this->scopeManager->getScopesForFilename($phpcsFile->getFilename()))) { + $scopesForFilename = $this->scopeManager->getScopesForFilename($phpcsFile->getFilename()); + if (empty($scopesForFilename)) { $this->scopeManager->recordScopeStartAndEnd($phpcsFile, 0); } From 6a084654a2d908a738c083fe75be4e2131472e4d Mon Sep 17 00:00:00 2001 From: Payton Swick Date: Sat, 23 Jul 2022 23:06:31 -0400 Subject: [PATCH 11/11] Remove unused imports --- VariableAnalysis/Lib/ScopeManager.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/VariableAnalysis/Lib/ScopeManager.php b/VariableAnalysis/Lib/ScopeManager.php index 5b0e261..ae3b029 100644 --- a/VariableAnalysis/Lib/ScopeManager.php +++ b/VariableAnalysis/Lib/ScopeManager.php @@ -3,13 +3,8 @@ namespace VariableAnalysis\Lib; use VariableAnalysis\Lib\ScopeInfo; -use VariableAnalysis\Lib\ScopeType; -use VariableAnalysis\Lib\VariableInfo; -use VariableAnalysis\Lib\Constants; use VariableAnalysis\Lib\Helpers; -use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; -use PHP_CodeSniffer\Util\Tokens; class ScopeManager { @@ -32,7 +27,7 @@ class ScopeManager * * @return ScopeInfo */ - public function recordScopeStartAndEnd($phpcsFile, $scopeStartIndex) + public function recordScopeStartAndEnd(File $phpcsFile, $scopeStartIndex) { $scopeEndIndex = Helpers::getScopeCloseForScopeOpen($phpcsFile, $scopeStartIndex); $filename = $phpcsFile->getFilename();