Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into fixer-conflict/PS…
Browse files Browse the repository at this point in the history
…R12.ControlStructures.ControlStructureSpacing
  • Loading branch information
fredden committed Sep 2, 2024
2 parents c52b6ed + 41a426c commit d931828
Show file tree
Hide file tree
Showing 34 changed files with 668 additions and 23 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ jobs:
runs-on: ubuntu-latest
name: "Build Phar on PHP: 8.0"

permissions:
id-token: write
contents: read
attestations: write

steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -39,6 +44,17 @@ jobs:
- name: Build the phar
run: php scripts/build-phar.php

# Provide provenance for generated binaries.
# Only attests the build artifacts which will be used in the published releases as per the guidelines in "what to attest".
# https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds
- name: Generate artifact attestations
if: ${{ github.ref_type == 'tag' }}
uses: actions/attest-build-provenance@v1
with:
subject-path: |
${{ github.workspace }}/phpcs.phar
${{ github.workspace }}/phpcbf.phar
- name: Upload the PHPCS phar
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ _Nothing yet._
- **_In contrast to earlier information, the `squizlabs/php_codesniffer` package now points to the new repository and everything will continue to work as before._**
- PHIVE users may need to clear the PHIVE URL cache.
- PHIVE users who don't use the package alias, but refer to the package URL, will need to update the URL from `https://squizlabs.github.io/PHP_CodeSniffer/phars/` to `https://phars.phpcodesniffer.com/phars/`.
- Users who download the PHAR files using curl or wget, will need to update the download URL from `https://squizlabs.github.io/PHP_CodeSniffer/[phpcs|phpcbf].phar` or `https://github.com/squizlabs/PHP_CodeSnifffer/releases/latest/download/[phpcs|phpcbf].phar` to `https://phars.phpcodesniffer.com/[phpcs|phpcbf].phar`.
- Users who download the PHAR files using curl or wget, will need to update the download URL from `https://squizlabs.github.io/PHP_CodeSniffer/[phpcs|phpcbf].phar` or `https://github.com/squizlabs/PHP_CodeSniffer/releases/latest/download/[phpcs|phpcbf].phar` to `https://phars.phpcodesniffer.com/[phpcs|phpcbf].phar`.
- For users who install PHP_CodeSniffer via the [Setup-PHP](https://github.com/shivammathur/setup-php/) action runner for GitHub Actions, nothing changes.
- Users using a git clone will need to update the clone address from `[email protected]:squizlabs/PHP_CodeSniffer.git` to `[email protected]:PHPCSStandards/PHP_CodeSniffer.git`.
- Contributors will need to fork the new repo and add both the new fork as well as the new repo as remotes to their local git copy of PHP_CodeSniffer.
Expand Down
5 changes: 5 additions & 0 deletions src/Sniffs/AbstractPatternSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,11 @@ protected function processPattern($patternInfo, File $phpcsFile, $stackPtr)
$lastAddedStackPtr = null;
$patternLen = count($pattern);

if (($stackPtr + $patternLen - $patternInfo['listen_pos']) > $phpcsFile->numTokens) {
// Pattern can never match as there are not enough tokens left in the file.
return false;
}

for ($i = $patternInfo['listen_pos']; $i < $patternLen; $i++) {
if (isset($tokens[$stackPtr]) === false) {
break;
Expand Down
5 changes: 1 addition & 4 deletions src/Standards/Generic/Sniffs/PHP/LowerCaseKeywordSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,12 @@ public function register()
{
$targets = Tokens::$contextSensitiveKeywords;
$targets += [
T_ANON_CLASS => T_ANON_CLASS,
T_CLOSURE => T_CLOSURE,
T_EMPTY => T_EMPTY,
T_ENUM_CASE => T_ENUM_CASE,
T_EVAL => T_EVAL,
T_ISSET => T_ISSET,
T_MATCH_DEFAULT => T_MATCH_DEFAULT,
T_PARENT => T_PARENT,
T_SELF => T_SELF,
T_UNSET => T_UNSET,
];

return $targets;
Expand Down
9 changes: 9 additions & 0 deletions src/Standards/Generic/Tests/PHP/LowerCaseKeywordUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,14 @@ EnuM ENUM: string
Case HEARTS;
}

new Class {};
new clasS extends stdClass {};
new class {};

if (isset($a) && !empty($a)) { unset($a); }
if (ISSET($a) && !Empty($a)) { UnSeT($a); }
eval('foo');
eVaL('foo');

__HALT_COMPILER(); // An exception due to phar support.
function
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,14 @@ enum ENUM: string
case HEARTS;
}

new class {};
new class extends stdClass {};
new class {};

if (isset($a) && !empty($a)) { unset($a); }
if (isset($a) && !empty($a)) { unset($a); }
eval('foo');
eval('foo');

__HALT_COMPILER(); // An exception due to phar support.
function
4 changes: 4 additions & 0 deletions src/Standards/Generic/Tests/PHP/LowerCaseKeywordUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public function getErrorList()
39 => 2,
42 => 1,
44 => 1,
47 => 1,
48 => 1,
52 => 3,
54 => 1,
];

}//end getErrorList()
Expand Down
14 changes: 11 additions & 3 deletions src/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,23 @@ protected function getDeclarationNameWithNamespace(array $tokens, $stackPtr)
*/
protected function getNamespaceOfScope(File $phpcsFile, $stackPtr)
{
$namespace = '\\';
$namespaceDeclaration = $phpcsFile->findPrevious(T_NAMESPACE, $stackPtr);
$namespace = '\\';
$tokens = $phpcsFile->getTokens();

while (($namespaceDeclaration = $phpcsFile->findPrevious(T_NAMESPACE, $stackPtr)) !== false) {
$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($namespaceDeclaration + 1), null, true);
if ($tokens[$nextNonEmpty]['code'] === T_NS_SEPARATOR) {
// Namespace operator. Ignore.
$stackPtr = ($namespaceDeclaration - 1);
continue;
}

if ($namespaceDeclaration !== false) {
$endOfNamespaceDeclaration = $phpcsFile->findNext([T_SEMICOLON, T_OPEN_CURLY_BRACKET, T_CLOSE_TAG], $namespaceDeclaration);
$namespace = $this->getDeclarationNameWithNamespace(
$phpcsFile->getTokens(),
($endOfNamespaceDeclaration - 1)
);
break;
}

return $namespace;
Expand Down
17 changes: 12 additions & 5 deletions src/Standards/Squiz/Sniffs/Formatting/OperatorBracketSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,16 +354,23 @@ public function addMissingBracketsError($phpcsFile, $stackPtr)
}

if ($tokens[$after]['code'] === T_OPEN_PARENTHESIS) {
if (isset($tokens[$after]['parenthesis_closer']) === false) {
// Live coding/parse error. Ignore.
return;
}

$after = $tokens[$after]['parenthesis_closer'];
continue;
}

if ($tokens[$after]['code'] === T_OPEN_SQUARE_BRACKET) {
$after = $tokens[$after]['bracket_closer'];
continue;
}
if (($tokens[$after]['code'] === T_OPEN_SQUARE_BRACKET
|| $tokens[$after]['code'] === T_OPEN_SHORT_ARRAY)
) {
if (isset($tokens[$after]['bracket_closer']) === false) {
// Live coding/parse error. Ignore.
return;
}

if ($tokens[$after]['code'] === T_OPEN_SHORT_ARRAY) {
$after = $tokens[$after]['bracket_closer'];
continue;
}
Expand Down
12 changes: 8 additions & 4 deletions src/Standards/Squiz/Sniffs/PHP/EmbeddedPhpSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,14 @@ private function validateInlineEmbeddedPhp($phpcsFile, $stackPtr, $closeTag)
}

// Check that there is one, and only one space at the start of the statement.
$leadingSpace = 0;
if ($tokens[$stackPtr]['code'] === T_OPEN_TAG) {
$leadingSpace = 0;
$isLongOpenTag = false;
if ($tokens[$stackPtr]['code'] === T_OPEN_TAG
&& stripos($tokens[$stackPtr]['content'], '<?php') === 0
) {
// The long open tag token in a single line tag set always contains a single space after it.
$leadingSpace = 1;
$leadingSpace = 1;
$isLongOpenTag = true;
}

if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) {
Expand All @@ -394,7 +398,7 @@ private function validateInlineEmbeddedPhp($phpcsFile, $stackPtr, $closeTag)
$data = [$leadingSpace];
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'SpacingAfterOpen', $data);
if ($fix === true) {
if ($tokens[$stackPtr]['code'] === T_OPEN_TAG) {
if ($isLongOpenTag === true) {
$phpcsFile->fixer->replaceToken(($stackPtr + 1), '');
} else if ($tokens[($stackPtr + 1)]['code'] === T_WHITESPACE) {
// Short open tag with too much whitespace.
Expand Down
14 changes: 14 additions & 0 deletions src/Standards/Squiz/Tests/Classes/SelfMemberReferenceUnitTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,17 @@ class Baz {
\EndsIn\CloseTag\Baz::something();
}
}

// Issue PHPCSStandards/PHP_CodeSniffer#553.
namespace TestMe;

namespace\functionCall();
namespace\anotherFunctionCall();

class SelfMemberReference
{
public function falseNegative()
{
$testResults[] = \TestMe\SelfMemberReference::test();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,17 @@ class Baz {
self::something();
}
}

// Issue PHPCSStandards/PHP_CodeSniffer#553.
namespace TestMe;

namespace\functionCall();
namespace\anotherFunctionCall();

class SelfMemberReference
{
public function falseNegative()
{
$testResults[] = self::test();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public function getErrorList()
162 => 1,
171 => 1,
183 => 1,
197 => 1,
];

}//end getErrorList()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

// Intentional parse error. This has to be the last (and only) test in the file.
// Live coding test. The sniff should stay silent.
class ParseErrors {
const A|(B PARSE_ERROR = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

// Intentional parse error. This has to be the last (and only) test in the file.
// Live coding test. The sniff should stay silent.
$a = [10, 20] + [
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class OperatorBracketUnitTest extends AbstractSniffUnitTest
public function getErrorList($testFile='')
{
switch ($testFile) {
case 'OperatorBracketUnitTest.inc':
case 'OperatorBracketUnitTest.1.inc':
return [
3 => 1,
6 => 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

// Intentional parse error. This has to be the last (and only) test in the file.
// Live coding test. The sniff should stay silent.
function
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

// Intentional parse error. This has to be the last (and only) test in the file.
// Live coding test. The sniff should stay silent.
function // Comment.
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,22 @@ final class FunctionDeclarationUnitTest extends AbstractSniffUnitTest
* The key of the array should represent the line number and the value
* should represent the number of errors that should occur on that line.
*
* @param string $testFile The name of the file being tested.
*
* @return array<int, int>
*/
public function getErrorList()
public function getErrorList($testFile='')
{
return [
55 => 1,
68 => 1,
];
switch ($testFile) {
case 'FunctionDeclarationUnitTest.1.inc':
return [
55 => 1,
68 => 1,
];

default:
return [];
}//end switch

}//end getErrorList()

Expand Down
4 changes: 4 additions & 0 deletions src/Standards/Squiz/Tests/PHP/EmbeddedPhpUnitTest.1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ echo 'the PHP tag is correctly indented as an indent less than the previous code
echo 'the PHP tag is incorrectly indented as the indent is more than 4 different from the indent of the previous code';
?>

<?PHP echo 'Uppercase long open tag'; ?>

<?PHP echo 'Extra space after uppercase long open tag '; ?>

<?php
// This test case file MUST always end with an unclosed long open PHP tag (with this comment) to prevent
// the tests running into the "last PHP closing tag excepted" condition breaking tests.
Expand Down
4 changes: 4 additions & 0 deletions src/Standards/Squiz/Tests/PHP/EmbeddedPhpUnitTest.1.inc.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ echo 'the PHP tag is correctly indented as an indent less than the previous code
echo 'the PHP tag is incorrectly indented as the indent is more than 4 different from the indent of the previous code';
?>

<?PHP echo 'Uppercase long open tag'; ?>

<?PHP echo 'Extra space after uppercase long open tag '; ?>

<?php
// This test case file MUST always end with an unclosed long open PHP tag (with this comment) to prevent
// the tests running into the "last PHP closing tag excepted" condition breaking tests.
Expand Down
25 changes: 25 additions & 0 deletions src/Standards/Squiz/Tests/PHP/EmbeddedPhpUnitTest.24.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?

// This test case file MUST always start with a open PHP tag set (with this comment) to prevent
// the tests running into the "first PHP open tag excepted" condition breaking the tests.
// Tests related to that "first PHP open tag excepted" condition should go in separate files.

// This test case file only deals with SHORT OPEN TAGS.

?>

<?
/* Contrary to the long open tag token, the short open tag token does not contain a space after the
tag and the sniff should handle it accordingly. The test below protects against regressions
related to https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/588. */
?>
<? echo 'one space after short open tag'; ?>

<? echo 'two spaces after short open tag'; ?>

<?echo 'without space after short open tag'; ?>

<?
// This test case file MUST always end with an unclosed open PHP tag (with this comment) to prevent
// the tests running into the "last PHP closing tag excepted" condition breaking tests.
// Tests related to that "last PHP closing tag excepted" condition should go in separate files.
25 changes: 25 additions & 0 deletions src/Standards/Squiz/Tests/PHP/EmbeddedPhpUnitTest.24.inc.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?

// This test case file MUST always start with a open PHP tag set (with this comment) to prevent
// the tests running into the "first PHP open tag excepted" condition breaking the tests.
// Tests related to that "first PHP open tag excepted" condition should go in separate files.

// This test case file only deals with SHORT OPEN TAGS.

?>

<?
/* Contrary to the long open tag token, the short open tag token does not contain a space after the
tag and the sniff should handle it accordingly. The test below protects against regressions
related to https://github.com/PHPCSStandards/PHP_CodeSniffer/issues/588. */
?>
<? echo 'one space after short open tag'; ?>

<? echo 'two spaces after short open tag'; ?>

<? echo 'without space after short open tag'; ?>

<?
// This test case file MUST always end with an unclosed open PHP tag (with this comment) to prevent
// the tests running into the "last PHP closing tag excepted" condition breaking tests.
// Tests related to that "last PHP closing tag excepted" condition should go in separate files.
11 changes: 11 additions & 0 deletions src/Standards/Squiz/Tests/PHP/EmbeddedPhpUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public function getErrorList($testFile='')
258 => 1,
263 => 1,
264 => 1,
270 => 1,
];

case 'EmbeddedPhpUnitTest.2.inc':
Expand Down Expand Up @@ -190,6 +191,16 @@ public function getErrorList($testFile='')
22 => 2,
];

case 'EmbeddedPhpUnitTest.24.inc':
$shortOpenTagDirective = (bool) ini_get('short_open_tag');
if ($shortOpenTagDirective === true) {
return [
18 => 1,
20 => 1,
];
}
return [];

default:
return [];
}//end switch
Expand Down
Loading

0 comments on commit d931828

Please sign in to comment.