From bc8d7e30e2005bce5c59018b7cdb08e9fb45c0d1 Mon Sep 17 00:00:00 2001 From: Bill Ruddock Date: Wed, 26 Jun 2024 21:08:34 +0100 Subject: [PATCH] fix: Process variable before the end of scope (#324) * test: add test for variable use in short open echo When a variable is used in a short php open echo tag, it should be marked as used. * fix: process variable before the end of scope fixes #323 When the last php code is a short php open echo tag using a variable, process the variable before processing the end of scope. --- .../ShortPhpTagsTest.php | 31 +++++++++++++++++++ .../fixtures/ShortPhpTagsFixture.php | 10 ++++++ .../CodeAnalysis/VariableAnalysisSniff.php | 12 ++++--- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 Tests/VariableAnalysisSniff/ShortPhpTagsTest.php create mode 100644 Tests/VariableAnalysisSniff/fixtures/ShortPhpTagsFixture.php diff --git a/Tests/VariableAnalysisSniff/ShortPhpTagsTest.php b/Tests/VariableAnalysisSniff/ShortPhpTagsTest.php new file mode 100644 index 0000000..79ce144 --- /dev/null +++ b/Tests/VariableAnalysisSniff/ShortPhpTagsTest.php @@ -0,0 +1,31 @@ +getFixture('ShortPhpTagsFixture.php'); + $phpcsFile = $this->prepareLocalFileForSniffs($fixtureFile); + $phpcsFile->process(); + $lines = $this->getWarningLineNumbersFromFile($phpcsFile); + $expectedWarnings = [ + 4, + 7, + ]; + $this->assertSame($expectedWarnings, $lines); + } + + public function testVariableWarningsHaveCorrectSniffCodesWhenShortEchoTagsAreUsed() + { + $fixtureFile = $this->getFixture('ShortPhpTagsFixture.php'); + $phpcsFile = $this->prepareLocalFileForSniffs($fixtureFile); + $phpcsFile->process(); + $warnings = $phpcsFile->getWarnings(); + $this->assertSame(self::UNUSED_ERROR_CODE, $warnings[4][1][0]['source']); + $this->assertSame(self::UNDEFINED_ERROR_CODE, $warnings[7][5][0]['source']); + } +} diff --git a/Tests/VariableAnalysisSniff/fixtures/ShortPhpTagsFixture.php b/Tests/VariableAnalysisSniff/fixtures/ShortPhpTagsFixture.php new file mode 100644 index 0000000..7ce7754 --- /dev/null +++ b/Tests/VariableAnalysisSniff/fixtures/ShortPhpTagsFixture.php @@ -0,0 +1,10 @@ + + + undefined variable + + used as last php statement without semicolon + diff --git a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php index 0aee22a..a08f7b1 100644 --- a/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php +++ b/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php @@ -245,6 +245,13 @@ public function process(File $phpcsFile, $stackPtr) $this->scopeManager->recordScopeStartAndEnd($phpcsFile, 0); } + // Find and process variables to perform two jobs: to record variable + // definition or use, and to report variables as undefined if they are used + // without having been first defined. + if ($token['code'] === T_VARIABLE) { + $this->processVariable($phpcsFile, $stackPtr); + } + // Report variables defined but not used in the current scope as unused // variables if the current token closes scopes. $this->searchForAndProcessClosingScopesAt($phpcsFile, $stackPtr); @@ -253,13 +260,10 @@ public function process(File $phpcsFile, $stackPtr) // expression of a for loop if the current token closes a loop. $this->processClosingForLoopsAt($phpcsFile, $stackPtr); - // Find and process variables to perform two jobs: to record variable - // definition or use, and to report variables as undefined if they are used - // without having been first defined. if ($token['code'] === T_VARIABLE) { - $this->processVariable($phpcsFile, $stackPtr); return; } + if (($token['code'] === T_DOUBLE_QUOTED_STRING) || ($token['code'] === T_HEREDOC)) { $this->processVariableInString($phpcsFile, $stackPtr); return;