diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index f3183d9b..8257b73c 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -7,7 +7,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
+ php-versions: ['7.4', '8.0', '8.1', '8.2', '8.3']
extra-tests: ['0']
# We only need to run PHPStan and Drupal core regression tests once on
# the latest PHP version.
@@ -82,4 +82,14 @@ jobs:
# ignored temporarily, add them with the --ignore option.
run: |
cd drupal/core
- ../../vendor/bin/phpcs -p -s --parallel=$(nproc)
+ # Fix Drupal core PHPCS config by replacing removed sniffs.
+ sed -i 's/Drupal.Classes.ClassCreateInstance/SlevomatCodingStandard.ControlStructures.NewWithParentheses/g' phpcs.xml.dist
+ sed -i 's/Drupal.Classes.UnusedUseStatement/SlevomatCodingStandard.Namespaces.UnusedUses/g' phpcs.xml.dist
+ sed -i '//a \ ' phpcs.xml.dist
+ find . -type f -name "*.php" -exec sed -i 's#// phpcs:ignore Drupal.Classes.PropertyDeclaration, Drupal.NamingConventions.ValidVariableName.LowerCamelName, Drupal.Commenting.VariableComment.Missing#// phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName,PSR2.Classes.PropertyDeclaration.Underscore#g' {} +
+ find . -type f -name "*.php" -exec sed -i 's#// @codingStandardsIgnoreLine#// phpcs:ignore#g' {} +
+ find . -type f -name "*.php" -exec sed -i 's#// @codingStandardsIgnoreFile#// phpcs:ignoreFile#g' {} +
+ find . -type f -exec sed -i '/\/\/ phpcs:ignore/ s/, /,/g' {} +
+ find . -type f -name "*.php" -exec sed -i 's#// @codingStandardsIgnoreStart#// phpcs:disable#g' {} +
+ find . -type f -name "*.php" -exec sed -i 's#// @codingStandardsIgnoreEnd#// phpcs:enable#g' {} +
+ ../../vendor/bin/phpcs -p -s --parallel=$(nproc) --ignore=lib/Drupal/Core/Command/GenerateTheme.php,modules/mysql/tests/src/Kernel/mysql/Console/DbDumpCommandTest.php
diff --git a/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php b/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php
deleted file mode 100644
index 7d067fe6..00000000
--- a/coder_sniffer/Drupal/Sniffs/Classes/ClassCreateInstanceSniff.php
+++ /dev/null
@@ -1,125 +0,0 @@
-
- */
- public function register()
- {
- return [T_NEW];
-
- }//end register()
-
-
- /**
- * Processes this test, when one of its tokens is encountered.
- *
- * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
- * @param int $stackPtr The position of the current token in the
- * stack passed in $tokens.
- *
- * @return void
- */
- public function process(File $phpcsFile, $stackPtr)
- {
- $tokens = $phpcsFile->getTokens();
-
- $commaOrColon = $phpcsFile->findNext([T_SEMICOLON, T_COLON, T_COMMA], ($stackPtr + 1));
- if ($commaOrColon === false) {
- // Syntax error, nothing we can do.
- return;
- }
-
- // Search for an opening parenthesis in the current statement until the
- // next semicolon or comma.
- $nextParenthesis = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($stackPtr + 1), $commaOrColon);
- if ($nextParenthesis === false) {
- $error = 'Calling class constructors must always include parentheses';
- $constructor = $phpcsFile->findNext(Tokens::EMPTY_TOKENS, ($stackPtr + 1), null, true, null, true);
- // We can invoke the fixer if we know this is a static constructor
- // function call or constructor calls with namespaces, example
- // "new \DOMDocument;" or constructor with class names in variables
- // "new $controller;".
- if ($tokens[$constructor]['code'] === T_STRING
- || $tokens[$constructor]['code'] === T_NS_SEPARATOR
- || ($tokens[$constructor]['code'] === T_VARIABLE
- && $tokens[($constructor + 1)]['code'] === T_SEMICOLON)
- ) {
- // Scan to the end of possible string\namespace parts.
- $nextConstructorPart = $constructor;
- while (true) {
- $nextConstructorPart = $phpcsFile->findNext(
- Tokens::EMPTY_TOKENS,
- ($nextConstructorPart + 1),
- null,
- true,
- null,
- true
- );
- if ($nextConstructorPart === false
- || ($tokens[$nextConstructorPart]['code'] !== T_STRING
- && $tokens[$nextConstructorPart]['code'] !== T_NS_SEPARATOR)
- ) {
- break;
- }
-
- $constructor = $nextConstructorPart;
- }
-
- $fix = $phpcsFile->addFixableError($error, $constructor, 'ParenthesisMissing');
- if ($fix === true) {
- $phpcsFile->fixer->addContent($constructor, '()');
- }
-
- // We can invoke the fixer if we know this is a
- // constructor call with class names in an array
- // example "new $controller[$i];".
- } else if ($tokens[$constructor]['code'] === T_VARIABLE
- && $tokens[($constructor + 1)]['code'] === T_OPEN_SQUARE_BRACKET
- ) {
- // Scan to the end of possible multilevel arrays.
- $nextConstructorPart = $constructor;
- do {
- $nextConstructorPart = $tokens[($nextConstructorPart + 1)]['bracket_closer'];
- } while ($tokens[($nextConstructorPart + 1)]['code'] === T_OPEN_SQUARE_BRACKET);
-
- $fix = $phpcsFile->addFixableError($error, $nextConstructorPart, 'ParenthesisMissing');
- if ($fix === true) {
- $phpcsFile->fixer->addContent($nextConstructorPart, '()');
- }
- } else {
- $phpcsFile->addError($error, $stackPtr, 'ParenthesisMissing');
- }//end if
- }//end if
-
- }//end process()
-
-
-}//end class
diff --git a/coder_sniffer/Drupal/Sniffs/Classes/FullyQualifiedNamespaceSniff.php b/coder_sniffer/Drupal/Sniffs/Classes/FullyQualifiedNamespaceSniff.php
index eac0e35a..c4ef66e6 100644
--- a/coder_sniffer/Drupal/Sniffs/Classes/FullyQualifiedNamespaceSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Classes/FullyQualifiedNamespaceSniff.php
@@ -11,6 +11,7 @@
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
+use PHP_CodeSniffer\Util\Tokens;
/**
* Checks that class references do not use FQN but use statements.
@@ -30,7 +31,10 @@ class FullyQualifiedNamespaceSniff implements Sniff
*/
public function register()
{
- return [T_NS_SEPARATOR];
+ return [
+ T_NAME_FULLY_QUALIFIED,
+ T_NAME_QUALIFIED,
+ ];
}//end register()
@@ -61,7 +65,9 @@ public function process(File $phpcsFile, $stackPtr)
// We are only interested in a backslash embedded between strings, which
// means this is a class reference with more than one namespace part.
- if ($tokens[($stackPtr - 1)]['code'] !== T_STRING || $tokens[($stackPtr + 1)]['code'] !== T_STRING) {
+ if (substr_count($tokens[$stackPtr]['content'], '\\') === 1
+ && strpos($tokens[$stackPtr]['content'], '\\') === 0
+ ) {
return;
}
@@ -71,25 +77,12 @@ public function process(File $phpcsFile, $stackPtr)
}
// Check if this is a use statement and ignore those.
- $before = $phpcsFile->findPrevious([T_STRING, T_NS_SEPARATOR, T_WHITESPACE, T_COMMA, T_AS], $stackPtr, null, true);
+ $before = $phpcsFile->findPrevious((Tokens::EMPTY_TOKENS + Tokens::NAME_TOKENS + [T_COMMA => T_COMMA, T_AS => T_AS]), ($stackPtr - 1), null, true);
if ($tokens[$before]['code'] === T_USE || $tokens[$before]['code'] === T_NAMESPACE) {
- return $phpcsFile->findNext([T_STRING, T_NS_SEPARATOR, T_WHITESPACE, T_COMMA, T_AS], ($stackPtr + 1), null, true);
- } else {
- $before = $phpcsFile->findPrevious([T_STRING, T_NS_SEPARATOR, T_WHITESPACE], $stackPtr, null, true);
- }
-
- // If this is a namespaced function call then ignore this because use
- // statements for functions are not possible in PHP 5.5 and lower.
- $after = $phpcsFile->findNext([T_STRING, T_NS_SEPARATOR, T_WHITESPACE], $stackPtr, null, true);
- if ($tokens[$after]['code'] === T_OPEN_PARENTHESIS
- && $tokens[$before]['code'] !== T_NEW
- && $tokens[$before]['code'] !== T_ATTRIBUTE
- ) {
- return ($after + 1);
+ return;
}
- $fullName = $phpcsFile->getTokensAsString(($before + 1), ($after - 1 - $before));
- $fullName = trim($fullName, "\ \n");
+ $fullName = trim($tokens[$stackPtr]['content'], '\\ ');
$parts = explode('\\', $fullName);
$className = end($parts);
@@ -101,7 +94,7 @@ public function process(File $phpcsFile, $stackPtr)
$useStatement = $phpcsFile->findNext(T_USE, 0);
while ($useStatement !== false && empty($tokens[$useStatement]['conditions']) === true) {
$endPtr = $phpcsFile->findEndOfStatement($useStatement);
- $useEnd = ($phpcsFile->findNext([T_STRING, T_NS_SEPARATOR, T_WHITESPACE], ($useStatement + 1), null, true) - 1);
+ $useEnd = ($phpcsFile->findNext((Tokens::EMPTY_TOKENS + Tokens::NAME_TOKENS), ($useStatement + 1), null, true) - 1);
$useFullName = trim($phpcsFile->getTokensAsString(($useStatement + 1), ($useEnd - $useStatement)));
// Check if use statement contains an alias.
@@ -163,18 +156,11 @@ public function process(File $phpcsFile, $stackPtr)
if ($fix === true) {
$phpcsFile->fixer->beginChangeset();
- // Replace the fully qualified name with the local name.
- for ($i = ($before + 1); $i < $after; $i++) {
- if ($tokens[$i]['code'] !== T_WHITESPACE) {
- $phpcsFile->fixer->replaceToken($i, '');
- }
- }
-
// Use alias name if available.
if ($aliasName !== false) {
- $phpcsFile->fixer->addContentBefore(($after - 1), $aliasName);
+ $phpcsFile->fixer->replaceToken($stackPtr, $aliasName);
} else {
- $phpcsFile->fixer->addContentBefore(($after - 1), $className);
+ $phpcsFile->fixer->replaceToken($stackPtr, $className);
}
// Insert use statement at the beginning of the file if it is not there
@@ -216,10 +202,6 @@ public function process(File $phpcsFile, $stackPtr)
$phpcsFile->fixer->endChangeset();
}//end if
- // Continue after this class reference so that errors for this are not
- // flagged multiple times.
- return $phpcsFile->findNext([T_STRING, T_NS_SEPARATOR], ($stackPtr + 1), null, true);
-
}//end process()
diff --git a/coder_sniffer/Drupal/Sniffs/Classes/UnusedUseStatementSniff.php b/coder_sniffer/Drupal/Sniffs/Classes/UnusedUseStatementSniff.php
deleted file mode 100644
index 8f98d4fb..00000000
--- a/coder_sniffer/Drupal/Sniffs/Classes/UnusedUseStatementSniff.php
+++ /dev/null
@@ -1,211 +0,0 @@
-
- */
- public function register()
- {
- return [T_USE];
-
- }//end register()
-
-
- /**
- * Processes this test, when one of its tokens is encountered.
- *
- * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
- * @param int $stackPtr The position of the current token in
- * the stack passed in $tokens.
- *
- * @return void
- */
- public function process(File $phpcsFile, $stackPtr)
- {
- $tokens = $phpcsFile->getTokens();
-
- // Only check use statements in the global scope.
- if (empty($tokens[$stackPtr]['conditions']) === false) {
- return;
- }
-
- // Seek to the end of the statement and get the string before the semi colon.
- $semiColon = $phpcsFile->findEndOfStatement($stackPtr);
- if ($tokens[$semiColon]['code'] !== T_SEMICOLON) {
- return;
- }
-
- $classPtr = $phpcsFile->findPrevious(
- Tokens::EMPTY_TOKENS,
- ($semiColon - 1),
- null,
- true
- );
-
- if ($tokens[$classPtr]['code'] !== T_STRING) {
- return;
- }
-
- // Search where the class name is used. PHP treats class names case
- // insensitive, that's why we cannot search for the exact class name string
- // and need to iterate over all T_STRING tokens in the file.
- $classUsed = $phpcsFile->findNext(T_STRING, ($classPtr + 1));
- $lowerClassName = strtolower($tokens[$classPtr]['content']);
-
- // Check if the referenced class is in the same namespace as the current
- // file. If it is then the use statement is not necessary.
- $namespacePtr = $phpcsFile->findPrevious([T_NAMESPACE], $stackPtr);
- // Check if the use statement does aliasing with the "as" keyword. Aliasing
- // is allowed even in the same namespace.
- $aliasUsed = $phpcsFile->findPrevious(T_AS, ($classPtr - 1), $stackPtr);
-
- if ($namespacePtr !== false && $aliasUsed === false) {
- $nsEnd = $phpcsFile->findNext(
- [
- T_NS_SEPARATOR,
- T_STRING,
- T_WHITESPACE,
- ],
- ($namespacePtr + 1),
- null,
- true
- );
- $namespace = trim($phpcsFile->getTokensAsString(($namespacePtr + 1), ($nsEnd - $namespacePtr - 1)));
-
- $useNamespacePtr = $phpcsFile->findNext([T_STRING], ($stackPtr + 1));
- $useNamespaceEnd = $phpcsFile->findNext(
- [
- T_NS_SEPARATOR,
- T_STRING,
- ],
- ($useNamespacePtr + 1),
- null,
- true
- );
- $useNamespace = rtrim($phpcsFile->getTokensAsString($useNamespacePtr, ($useNamespaceEnd - $useNamespacePtr - 1)), '\\');
-
- if (strcasecmp($namespace, $useNamespace) === 0) {
- $classUsed = false;
- }
- }//end if
-
- while ($classUsed !== false) {
- if (strtolower($tokens[$classUsed]['content']) === $lowerClassName) {
- $beforeUsage = $phpcsFile->findPrevious(
- Tokens::EMPTY_TOKENS,
- ($classUsed - 1),
- null,
- true
- );
- // If a backslash is used before the class name then this is some other
- // use statement.
- if (in_array(
- $tokens[$beforeUsage]['code'],
- [
- T_USE,
- T_NS_SEPARATOR,
- // If an object operator is used then this is a method call
- // with the same name as the class name. Which means this is
- // not referring to the class.
- T_OBJECT_OPERATOR,
- // Function definition, not class invocation.
- T_FUNCTION,
- // Static method call, not class invocation.
- T_DOUBLE_COLON,
- ]
- ) === false
- ) {
- return;
- }
-
- // Trait use statement within a class.
- if ($tokens[$beforeUsage]['code'] === T_USE && empty($tokens[$beforeUsage]['conditions']) === false) {
- return;
- }
- }//end if
-
- $classUsed = $phpcsFile->findNext([T_STRING], ($classUsed + 1));
- }//end while
-
- $warning = 'Unused use statement';
- $fix = $phpcsFile->addFixableWarning($warning, $stackPtr, 'UnusedUse');
- if ($fix === true) {
- // Remove the whole use statement line.
- $phpcsFile->fixer->beginChangeset();
- for ($i = $stackPtr; $i <= $semiColon; $i++) {
- $phpcsFile->fixer->replaceToken($i, '');
- }
-
- // Also remove whitespace after the semicolon (new lines).
- while (isset($tokens[$i]) === true && $tokens[$i]['code'] === T_WHITESPACE) {
- $phpcsFile->fixer->replaceToken($i, '');
- if (strpos($tokens[$i]['content'], $phpcsFile->eolChar) !== false) {
- break;
- }
-
- $i++;
- }
-
- // Replace @var data types in doc comments with the fully qualified class
- // name.
- $useNamespacePtr = $phpcsFile->findNext([T_STRING], ($stackPtr + 1));
- $useNamespaceEnd = $phpcsFile->findNext(
- [
- T_NS_SEPARATOR,
- T_STRING,
- ],
- ($useNamespacePtr + 1),
- null,
- true
- );
- $fullNamespace = $phpcsFile->getTokensAsString($useNamespacePtr, ($useNamespaceEnd - $useNamespacePtr));
-
- $tag = $phpcsFile->findNext(T_DOC_COMMENT_TAG, ($stackPtr + 1));
-
- while ($tag !== false) {
- if (($tokens[$tag]['content'] === '@var' || $tokens[$tag]['content'] === '@return')
- && isset($tokens[($tag + 1)]) === true
- && $tokens[($tag + 1)]['code'] === T_DOC_COMMENT_WHITESPACE
- && isset($tokens[($tag + 2)]) === true
- && $tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING
- && strpos($tokens[($tag + 2)]['content'], $tokens[$classPtr]['content']) === 0
- ) {
- $replacement = '\\'.$fullNamespace.substr($tokens[($tag + 2)]['content'], strlen($tokens[$classPtr]['content']));
- $phpcsFile->fixer->replaceToken(($tag + 2), $replacement);
- }
-
- $tag = $phpcsFile->findNext(T_DOC_COMMENT_TAG, ($tag + 1));
- }
-
- $phpcsFile->fixer->endChangeset();
- }//end if
-
- }//end process()
-
-
-}//end class
diff --git a/coder_sniffer/Drupal/Sniffs/Classes/UseGlobalClassSniff.php b/coder_sniffer/Drupal/Sniffs/Classes/UseGlobalClassSniff.php
index 7319f104..2bf03c08 100644
--- a/coder_sniffer/Drupal/Sniffs/Classes/UseGlobalClassSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Classes/UseGlobalClassSniff.php
@@ -75,19 +75,20 @@ public function process(File $phpcsFile, $stackPtr)
$lineStart = $stackPtr;
// Iterate through a potential multiline use statement.
while (false !== $lineEnd = $phpcsFile->findNext([T_SEMICOLON, T_COMMA], ($lineStart + 1), ($stmtEnd + 1))) {
- // We are only interested in imports that contain no backslash,
- // which means this is a class without a namespace.
- // Also skip function imports.
- if ($phpcsFile->findNext(T_NS_SEPARATOR, $lineStart, $lineEnd) !== false
- || $phpcsFile->findNext(T_STRING, $lineStart, $lineEnd, false, 'function') !== false
- ) {
+ // Skip function imports.
+ if ($phpcsFile->findNext(T_STRING, $lineStart, $lineEnd, false, 'function') !== false) {
$lineStart = $lineEnd;
continue;
}
- // The first string token is the class name.
- $class = $phpcsFile->findNext(T_STRING, $lineStart, $lineEnd);
+ $class = $phpcsFile->findNext(Tokens::NAME_TOKENS, $lineStart, $lineEnd);
$className = $tokens[$class]['content'];
+ if (strpos($className, '\\') !== false) {
+ // This is a namespaced class, skip it.
+ $lineStart = $lineEnd;
+ continue;
+ }
+
// If there is more than one string token, the last one is the alias.
$alias = $phpcsFile->findPrevious(T_STRING, $lineEnd, $stackPtr);
$aliasName = $tokens[$alias]['content'];
@@ -125,9 +126,7 @@ public function process(File $phpcsFile, $stackPtr)
// Only start looking after the end of the use statement block.
$i = $bodyStart;
while (false !== $i = $phpcsFile->findNext(T_STRING, ($i + 1), null, false, $aliasName)) {
- if ($tokens[($i - 1)]['code'] !== T_NS_SEPARATOR) {
- $phpcsFile->fixer->replaceToken($i, '\\'.$className);
- }
+ $phpcsFile->fixer->replaceToken($i, '\\'.$className);
}
$phpcsFile->fixer->endChangeset();
diff --git a/coder_sniffer/Drupal/Sniffs/Classes/UseLeadingBackslashSniff.php b/coder_sniffer/Drupal/Sniffs/Classes/UseLeadingBackslashSniff.php
index 200ae848..0c323f6d 100644
--- a/coder_sniffer/Drupal/Sniffs/Classes/UseLeadingBackslashSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Classes/UseLeadingBackslashSniff.php
@@ -61,11 +61,11 @@ public function process(File $phpcsFile, $stackPtr)
true
);
- if ($startPtr !== false && $tokens[$startPtr]['code'] === T_NS_SEPARATOR) {
+ if ($startPtr !== false && $tokens[$startPtr]['code'] === T_NAME_FULLY_QUALIFIED) {
$error = 'When importing a class with "use", do not include a leading \\';
$fix = $phpcsFile->addFixableError($error, $startPtr, 'SeparatorStart');
if ($fix === true) {
- $phpcsFile->fixer->replaceToken($startPtr, '');
+ $phpcsFile->fixer->replaceToken($startPtr, ltrim($tokens[$startPtr]['content'], '\\'));
}
}
diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/DataTypeNamespaceSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/DataTypeNamespaceSniff.php
index bed4c6d1..7602dca7 100644
--- a/coder_sniffer/Drupal/Sniffs/Commenting/DataTypeNamespaceSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Commenting/DataTypeNamespaceSniff.php
@@ -67,23 +67,14 @@ public function process(File $phpcsFile, $stackPtr)
true
);
- if ($tokens[$classPtr]['code'] !== T_STRING) {
+ if (in_array($tokens[$classPtr]['code'], Tokens::NAME_TOKENS) === false) {
return;
}
// Replace @var data types in doc comments with the fully qualified class
// name.
- $useNamespacePtr = $phpcsFile->findNext([T_STRING], ($stackPtr + 1));
- $useNamespaceEnd = $phpcsFile->findNext(
- [
- T_NS_SEPARATOR,
- T_STRING,
- ],
- ($useNamespacePtr + 1),
- null,
- true
- );
- $fullNamespace = $phpcsFile->getTokensAsString($useNamespacePtr, ($useNamespaceEnd - $useNamespacePtr));
+ $fullNamespace = $tokens[$classPtr]['content'];
+ $className = substr($fullNamespace, (strrpos($fullNamespace, '\\') + 1));
$tag = $phpcsFile->findNext(T_DOC_COMMENT_TAG, ($stackPtr + 1));
@@ -96,13 +87,13 @@ public function process(File $phpcsFile, $stackPtr)
&& $tokens[($tag + 1)]['code'] === T_DOC_COMMENT_WHITESPACE
&& isset($tokens[($tag + 2)]) === true
&& $tokens[($tag + 2)]['code'] === T_DOC_COMMENT_STRING
- && strpos($tokens[($tag + 2)]['content'], $tokens[$classPtr]['content']) === 0
+ && strpos($tokens[($tag + 2)]['content'], $className) === 0
) {
$error = 'Data types in %s tags need to be fully namespaced';
$data = [$tokens[$tag]['content']];
$fix = $phpcsFile->addFixableError($error, ($tag + 2), 'DataTypeNamespace', $data);
if ($fix === true) {
- $replacement = '\\'.$fullNamespace.substr($tokens[($tag + 2)]['content'], strlen($tokens[$classPtr]['content']));
+ $replacement = '\\'.$fullNamespace.substr($tokens[($tag + 2)]['content'], strlen($className));
$phpcsFile->fixer->replaceToken(($tag + 2), $replacement);
}
}
diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/FileCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/FileCommentSniff.php
index 72b490d4..fc1d8de3 100644
--- a/coder_sniffer/Drupal/Sniffs/Commenting/FileCommentSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Commenting/FileCommentSniff.php
@@ -138,16 +138,12 @@ public function process(File $phpcsFile, $stackPtr)
if ($fix === true) {
// Only PHP has a real opening tag, additional newline at the
// beginning here.
- if ($phpcsFile->tokenizerType === 'PHP') {
- // In templates add the file doc block to the very beginning of
- // the file.
- if ($tokens[0]['code'] === T_INLINE_HTML) {
- $phpcsFile->fixer->addContentBefore(0, "\n");
- } else {
- $phpcsFile->fixer->addContent($stackPtr, "\n/**\n * @file\n */\n");
- }
+ // In templates add the file doc block to the very beginning of
+ // the file.
+ if ($tokens[0]['code'] === T_INLINE_HTML) {
+ $phpcsFile->fixer->addContentBefore(0, "\n");
} else {
- $phpcsFile->fixer->addContent($stackPtr, "/**\n * @file\n */\n");
+ $phpcsFile->fixer->addContent($stackPtr, "\n/**\n * @file\n */\n");
}
}
@@ -166,13 +162,7 @@ public function process(File $phpcsFile, $stackPtr)
if ($fileTag === false) {
$fix = $phpcsFile->addFixableError('Missing file doc comment', $stackPtr, 'Missing');
if ($fix === true) {
- // Only PHP has a real opening tag, additional newline at the
- // beginning here.
- if ($phpcsFile->tokenizerType === 'PHP') {
- $phpcsFile->fixer->addContent($stackPtr, "\n/**\n * @file\n */\n");
- } else {
- $phpcsFile->fixer->addContent($stackPtr, "/**\n * @file\n */\n");
- }
+ $phpcsFile->fixer->addContent($stackPtr, "\n/**\n * @file\n */\n");
}
return ($phpcsFile->numTokens + 1);
diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/InlineCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/InlineCommentSniff.php
index 49c77160..74415b79 100644
--- a/coder_sniffer/Drupal/Sniffs/Commenting/InlineCommentSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Commenting/InlineCommentSniff.php
@@ -83,7 +83,6 @@ public function process(File $phpcsFile, $stackPtr)
T_STATIC,
T_ABSTRACT,
T_CONST,
- T_PROPERTY,
T_INCLUDE,
T_INCLUDE_ONCE,
T_REQUIRE,
diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/VariableCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/VariableCommentSniff.php
index aef359ee..ac7c6fb2 100644
--- a/coder_sniffer/Drupal/Sniffs/Commenting/VariableCommentSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/Commenting/VariableCommentSniff.php
@@ -47,8 +47,6 @@ public function processMemberVar(File $phpcsFile, $stackPtr)
T_STATIC => T_STATIC,
T_READONLY => T_READONLY,
T_WHITESPACE => T_WHITESPACE,
- T_STRING => T_STRING,
- T_NS_SEPARATOR => T_NS_SEPARATOR,
T_NAMESPACE => T_NAMESPACE,
T_NULLABLE => T_NULLABLE,
T_TYPE_UNION => T_TYPE_UNION,
@@ -58,7 +56,7 @@ public function processMemberVar(File $phpcsFile, $stackPtr)
T_FALSE => T_FALSE,
T_SELF => T_SELF,
T_PARENT => T_PARENT,
- ] + Tokens::PHPCS_ANNOTATION_TOKENS);
+ ] + Tokens::PHPCS_ANNOTATION_TOKENS + Tokens::NAME_TOKENS);
for ($commentEnd = ($stackPtr - 1); $commentEnd >= 0; $commentEnd--) {
if (isset($ignore[$tokens[$commentEnd]['code']]) === true) {
@@ -133,7 +131,7 @@ public function processMemberVar(File $phpcsFile, $stackPtr)
if ($foundVar === null) {
// If there's an inline type argument then you may omit the @var comment.
// Check if there's a type between the variable name and the comment end.
- if ($phpcsFile->findPrevious([T_STRING], $stackPtr, $commentEnd) !== false) {
+ if ($phpcsFile->findPrevious(Tokens::NAME_TOKENS, $stackPtr, $commentEnd) !== false) {
return;
}
diff --git a/coder_sniffer/Drupal/Sniffs/WhiteSpace/OpenTagNewlineSniff.php b/coder_sniffer/Drupal/Sniffs/WhiteSpace/OpenTagNewlineSniff.php
index 0ac20d1f..302b52ac 100644
--- a/coder_sniffer/Drupal/Sniffs/WhiteSpace/OpenTagNewlineSniff.php
+++ b/coder_sniffer/Drupal/Sniffs/WhiteSpace/OpenTagNewlineSniff.php
@@ -48,6 +48,11 @@ public function register()
*/
public function process(File $phpcsFile, $stackPtr)
{
+ // This sniff only works when there are \n line endings.
+ if ($phpcsFile->eolChar !== "\n") {
+ return ($phpcsFile->numTokens + 1);
+ }
+
$tokens = $phpcsFile->getTokens();
// Only check the very first PHP open tag in a file, ignore any others.
diff --git a/coder_sniffer/Drupal/ruleset.xml b/coder_sniffer/Drupal/ruleset.xml
index 5eb990f3..7c6ad8d4 100644
--- a/coder_sniffer/Drupal/ruleset.xml
+++ b/coder_sniffer/Drupal/ruleset.xml
@@ -37,6 +37,10 @@
0
+
+
+ *.tpl.php
+
@@ -136,7 +140,10 @@
+
+
+
diff --git a/coder_sniffer/DrupalPractice/Project.php b/coder_sniffer/DrupalPractice/Project.php
index c7d6a6a5..464e6166 100644
--- a/coder_sniffer/DrupalPractice/Project.php
+++ b/coder_sniffer/DrupalPractice/Project.php
@@ -196,18 +196,9 @@ public static function isServiceClass(File $phpcsFile, $classPtr)
return false;
}
- $nsEnd = $phpcsFile->findNext(
- [
- T_NS_SEPARATOR,
- T_STRING,
- T_WHITESPACE,
- ],
- ($namespacePtr + 1),
- null,
- true
- );
- $namespace = trim($phpcsFile->getTokensAsString(($namespacePtr + 1), ($nsEnd - $namespacePtr - 1)));
- $classNameSpaced = ltrim($namespace.'\\'.$phpcsFile->getDeclarationName($classPtr), '\\');
+ $nameQualifiedPtr = $phpcsFile->findNext(T_NAME_QUALIFIED, ($namespacePtr + 1));
+ $namespace = ($phpcsFile->getTokens()[$nameQualifiedPtr]['content'] ?? '');
+ $classNameSpaced = ltrim($namespace.'\\'.$phpcsFile->getDeclarationName($classPtr), '\\');
foreach ($services['services'] as $service) {
if (isset($service['class']) === true
diff --git a/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalClassSniff.php b/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalClassSniff.php
index f84c74e5..e19ca290 100644
--- a/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalClassSniff.php
+++ b/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalClassSniff.php
@@ -181,12 +181,18 @@ protected function getFullyQualifiedName(File $phpcsFile, $className)
{
$useStatement = $phpcsFile->findNext(T_USE, 0);
while ($useStatement !== false) {
- $endPtr = $phpcsFile->findEndOfStatement($useStatement);
- $useEnd = ($phpcsFile->findNext([T_STRING, T_NS_SEPARATOR, T_WHITESPACE], ($useStatement + 1), null, true) - 1);
- $useFullName = trim($phpcsFile->getTokensAsString(($useStatement + 1), ($useEnd - $useStatement)), '\\ ');
+ $endPtr = $phpcsFile->findEndOfStatement($useStatement);
+ $useFullNamePtr = $phpcsFile->findNext([T_NAME_QUALIFIED, T_NAME_FULLY_QUALIFIED], ($useStatement + 1), $endPtr);
+ if ($useFullNamePtr === false) {
+ // No qualified name found, skip to next use statement.
+ $useStatement = $phpcsFile->findNext(T_USE, ($endPtr + 1));
+ continue;
+ }
+
+ $useFullName = trim($phpcsFile->getTokens()[$useFullNamePtr]['content'], '\\ ');
// Check if use statement contains an alias.
- $asPtr = $phpcsFile->findNext(T_AS, ($useEnd + 1), $endPtr);
+ $asPtr = $phpcsFile->findNext(T_AS, ($useFullNamePtr + 1), $endPtr);
if ($asPtr !== false) {
$aliasName = trim($phpcsFile->getTokensAsString(($asPtr + 1), ($endPtr - 1 - $asPtr)));
if ($aliasName === $className) {
diff --git a/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalDrupalSniff.php b/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalDrupalSniff.php
index 4148ba8e..91245f85 100644
--- a/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalDrupalSniff.php
+++ b/coder_sniffer/DrupalPractice/Sniffs/Objects/GlobalDrupalSniff.php
@@ -51,7 +51,7 @@ class GlobalDrupalSniff implements Sniff
*/
public function register()
{
- return [T_STRING];
+ return [T_NAME_FULLY_QUALIFIED];
}//end register()
@@ -71,7 +71,7 @@ public function process(File $phpcsFile, $stackPtr)
// We are only interested in Drupal:: static method calls, not in the global
// scope.
- if ($tokens[$stackPtr]['content'] !== 'Drupal'
+ if ($tokens[$stackPtr]['content'] !== '\Drupal'
|| $tokens[($stackPtr + 1)]['code'] !== T_DOUBLE_COLON
|| isset($tokens[($stackPtr + 2)]) === false
|| $tokens[($stackPtr + 2)]['code'] !== T_STRING
diff --git a/composer.json b/composer.json
index 5858f899..c9e0ec26 100644
--- a/composer.json
+++ b/composer.json
@@ -14,12 +14,12 @@
],
"license": "GPL-2.0-or-later",
"require": {
- "php": ">=7.2",
+ "php": ">=7.4",
"ext-mbstring": "*",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.1 || ^1.0.0",
- "sirbrillig/phpcs-variable-analysis": "^2.11.7",
- "slevomat/coding-standard": "^8.11",
- "squizlabs/php_codesniffer": "^3.13",
+ "sirbrillig/phpcs-variable-analysis": "^2.13",
+ "slevomat/coding-standard": "^8.24",
+ "squizlabs/php_codesniffer": "^4.0",
"symfony/yaml": ">=3.4.0"
},
"autoload": {
@@ -36,6 +36,6 @@
},
"require-dev": {
"phpstan/phpstan": "^1.7.12",
- "phpunit/phpunit": "^8.0"
+ "phpunit/phpunit": "^9.0"
}
}
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index f48d02d1..650e6c16 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -106,7 +106,6 @@
-
@@ -154,7 +153,9 @@
-
+
+
+
diff --git a/tests/Drupal/Classes/ClassCreateInstanceUnitTest.php b/tests/Drupal/Classes/ClassCreateInstanceUnitTest.php
deleted file mode 100644
index e220ea96..00000000
--- a/tests/Drupal/Classes/ClassCreateInstanceUnitTest.php
+++ /dev/null
@@ -1,59 +0,0 @@
-
- */
- protected function getErrorList(string $testFile): array
- {
- return [
- 3 => 1,
- 4 => 1,
- 5 => 1,
- 6 => 1,
- 8 => 1,
- 9 => 1,
- 10 => 1,
- 11 => 1,
- 12 => 1,
- 13 => 1,
- 14 => 1,
- 16 => 1,
- 31 => 1,
- ];
-
- }//end getErrorList()
-
-
- /**
- * Returns the lines where warnings should occur.
- *
- * The key of the array should represent the line number and the value
- * should represent the number of warnings that should occur on that line.
- *
- * @param string $testFile The name of the file being tested.
- *
- * @return array
- */
- protected function getWarningList(string $testFile): array
- {
- return [];
-
- }//end getWarningList()
-
-
-}//end class
diff --git a/tests/Drupal/Classes/ClassFileNameUnitTest.php b/tests/Drupal/Classes/ClassFileNameUnitTest.php
index 7cc4349a..c1fd3269 100644
--- a/tests/Drupal/Classes/ClassFileNameUnitTest.php
+++ b/tests/Drupal/Classes/ClassFileNameUnitTest.php
@@ -59,7 +59,7 @@ protected function getTestFiles($testFileBase): array
return [
__DIR__.'/drupal8/ClassFileNameUnitTest.php',
__DIR__.'/drupal8/drupal8.behat.inc',
- __DIR__.'/drupal7/class_fle_name_test.module',
+ __DIR__.'/drupal7/class_file_name_test.module',
__DIR__.'/drupal8/markdownFile.md',
];
diff --git a/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc b/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc
index 1819ef46..5ddd6d05 100644
--- a/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc
+++ b/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc
@@ -8,8 +8,8 @@
use Test\Bar;
use Test\NotUsed;
use Test\Alias as TestAlias;
-use Test\MultiLine as MultiLineAlias,
- Test\MultiLineSecond;
+use Test\MultiLine as MultiLineAlias;
+use Test\MultiLineSecond;
/**
* Example.
diff --git a/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc.fixed b/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc.fixed
index 004f9eaa..277c94b8 100644
--- a/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc.fixed
+++ b/tests/Drupal/Classes/FullyQualifiedNamespaceUnitTest.inc.fixed
@@ -6,11 +6,11 @@
*/
use Test\MultiLineSecond;
+use Test\MultiLine;
use Test\Foo;
use Test\NotUsed;
use Test\Bar;
use Test\Alias as TestAlias;
-use Test\MultiLine as MultiLineAlias;
/**
* Example.
@@ -69,7 +69,7 @@ class Example {
/**
* Description.
*/
- public function test8(MultiLineAlias $multiLine, MultiLineSecond $multiLineSecond) {
+ public function test8(MultiLine $multiLine, MultiLineSecond $multiLineSecond) {
}
diff --git a/tests/Drupal/Classes/UnusedUseStatementUnitTest.php b/tests/Drupal/Classes/UnusedUseStatementUnitTest.php
deleted file mode 100644
index 70950b9e..00000000
--- a/tests/Drupal/Classes/UnusedUseStatementUnitTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
-
- */
- protected function getErrorList(string $testFile): array
- {
- return [];
-
- }//end getErrorList()
-
-
- /**
- * Returns the lines where warnings should occur.
- *
- * The key of the array should represent the line number and the value
- * should represent the number of warnings that should occur on that line.
- *
- * @param string $testFile The name of the file being tested.
- *
- * @return array
- */
- protected function getWarningList(string $testFile): array
- {
- return [
- 5 => 1,
- 6 => 1,
- 7 => 1,
- 10 => 1,
- 11 => 1,
- 12 => 1,
- 14 => 1,
- 16 => 1,
- 17 => 1,
- 19 => 1,
- 20 => 1,
- 21 => 1,
- 22 => 1,
- 23 => 1,
- ];
-
- }//end getWarningList()
-
-
-}//end class
diff --git a/tests/Drupal/Classes/UseGlobalClassUnitTest.inc.fixed b/tests/Drupal/Classes/UseGlobalClassUnitTest.inc.fixed
index a1518555..40081c19 100644
--- a/tests/Drupal/Classes/UseGlobalClassUnitTest.inc.fixed
+++ b/tests/Drupal/Classes/UseGlobalClassUnitTest.inc.fixed
@@ -8,7 +8,6 @@
use Namespaced\TestClass;
use Namespaced\TestClassSecond as NamespacedAlias;
use Namespaced\MultiLine2 as MultiLineAlias2;
-use function count;
/**
* Example.
diff --git a/tests/Drupal/CoderSniffUnitTest.php b/tests/Drupal/CoderSniffUnitTest.php
index 4210b88b..e4fb08fb 100644
--- a/tests/Drupal/CoderSniffUnitTest.php
+++ b/tests/Drupal/CoderSniffUnitTest.php
@@ -17,7 +17,6 @@
use PHP_CodeSniffer\Ruleset;
use PHP_CodeSniffer\Files\LocalFile;
use PHP_CodeSniffer\Exceptions\RuntimeException;
-use PHP_CodeSniffer\Util\Common;
use PHP_CodeSniffer\Util\Tokens;
use PHPUnit\Framework\TestCase;
@@ -62,8 +61,6 @@ abstract class CoderSniffUnitTest extends TestCase
*/
public function setUp(): void
{
- $class = get_class($this);
-
$this->rootDir = __DIR__.'/../../';
$this->testsDir = __DIR__.'/';
// Required to pull in all the defines from the tokens file.
@@ -89,7 +86,7 @@ public function setUp(): void
*
* @return array
*/
- protected function getTestFiles($testFileBase): array
+ protected function getTestFiles(string $testFileBase): array
{
$testFiles = [];
@@ -140,7 +137,7 @@ final public function testSniff()
$this->markTestSkipped();
}
- $sniffCode = Common::getSniffCode(get_class($this));
+ $sniffCode = $this->getSniffCode(static::class);
list($standardName, $categoryName, $sniffName) = explode('.', $sniffCode);
// In the case where we are running all the sniffs, the standard will
@@ -423,6 +420,45 @@ public function generateFailureMessages(LocalFile $file): array
}//end generateFailureMessages()
+ /**
+ * Given a test class name, returns the code for the sniff.
+ *
+ * Forked from PHP_CodeSniffer\Util\Common to work with our test files.
+ *
+ * @param string $testClass The fully qualified test class name.
+ *
+ * @return string
+ *
+ * @throws \InvalidArgumentException When $testClass is not a non-empty string.
+ * @throws \InvalidArgumentException When $testClass is not a valid FQN for a test class.
+ */
+ public function getSniffCode(string $testClass): string
+ {
+ if ($testClass === '') {
+ throw new \InvalidArgumentException('The $testClass parameter must be a non-empty string');
+ }
+
+ $parts = explode('\\', $testClass);
+ $partsCount = count($parts);
+
+ $sniff = $parts[($partsCount - 1)];
+
+ if ($sniff !== 'UnitTest' && substr($sniff, -8) === 'UnitTest') {
+ // Unit test class name.
+ $sniff = substr($sniff, 0, -8);
+ } else {
+ throw new \InvalidArgumentException(
+ 'The $testClass parameter was not passed a fully qualified sniff(test) class name. Received: '.$testClass
+ );
+ }
+
+ $standard = $parts[($partsCount - 4)];
+ $category = $parts[($partsCount - 2)];
+ return $standard.'.'.$category.'.'.$sniff;
+
+ }//end getSniffCode()
+
+
/**
* Set a list of CLI values before the file is tested.
*
diff --git a/tests/Drupal/bad/BadUnitTest.php b/tests/Drupal/bad/BadUnitTest.php
index 4312e07b..bd0ebf86 100644
--- a/tests/Drupal/bad/BadUnitTest.php
+++ b/tests/Drupal/bad/BadUnitTest.php
@@ -29,7 +29,7 @@ protected function getErrorList(string $testFile): array
switch ($testFile) {
case 'bad_crlf.inc':
return [
- 1 => 2,
+ 1 => 1,
8 => 1,
];
case 'bad.info':
@@ -367,6 +367,43 @@ protected function getErrorList(string $testFile): array
872 => 1,
876 => 2,
];
+ case 'ClassCreateInstanceUnitTest.inc':
+ return [
+ 3 => 1,
+ 4 => 1,
+ 5 => 1,
+ 6 => 1,
+ 8 => 1,
+ 9 => 1,
+ 10 => 1,
+ 11 => 1,
+ 12 => 2,
+ 13 => 2,
+ 14 => 2,
+ 16 => 1,
+ 31 => 1,
+ ];
+ case 'UnusedUseStatementUnitTest.inc':
+ return [
+ 5 => 1,
+ 6 => 1,
+ 7 => 1,
+ 10 => 1,
+ 11 => 1,
+ 12 => 1,
+ 14 => 1,
+ 16 => 1,
+ 17 => 2,
+ 19 => 1,
+ 20 => 1,
+ 21 => 1,
+ 22 => 1,
+ 23 => 1,
+ 35 => 1,
+ 56 => 1,
+ 85 => 1,
+ 98 => 1,
+ ];
}//end switch
return [];
diff --git a/tests/Drupal/Classes/ClassCreateInstanceUnitTest.inc b/tests/Drupal/bad/ClassCreateInstanceUnitTest.inc
similarity index 100%
rename from tests/Drupal/Classes/ClassCreateInstanceUnitTest.inc
rename to tests/Drupal/bad/ClassCreateInstanceUnitTest.inc
diff --git a/tests/Drupal/Classes/ClassCreateInstanceUnitTest.inc.fixed b/tests/Drupal/bad/ClassCreateInstanceUnitTest.inc.fixed
similarity index 100%
rename from tests/Drupal/Classes/ClassCreateInstanceUnitTest.inc.fixed
rename to tests/Drupal/bad/ClassCreateInstanceUnitTest.inc.fixed
diff --git a/tests/Drupal/Classes/UnusedUseStatementUnitTest.inc b/tests/Drupal/bad/UnusedUseStatementUnitTest.inc
similarity index 100%
rename from tests/Drupal/Classes/UnusedUseStatementUnitTest.inc
rename to tests/Drupal/bad/UnusedUseStatementUnitTest.inc
diff --git a/tests/Drupal/Classes/UnusedUseStatementUnitTest.inc.fixed b/tests/Drupal/bad/UnusedUseStatementUnitTest.inc.fixed
similarity index 96%
rename from tests/Drupal/Classes/UnusedUseStatementUnitTest.inc.fixed
rename to tests/Drupal/bad/UnusedUseStatementUnitTest.inc.fixed
index 2c620518..93b5fe68 100644
--- a/tests/Drupal/Classes/UnusedUseStatementUnitTest.inc.fixed
+++ b/tests/Drupal/bad/UnusedUseStatementUnitTest.inc.fixed
@@ -26,7 +26,7 @@ class Pum {
/**
* Aliased type that is otherwise unused.
*
- * @var \Some\Data\VarName2
+ * @var AliasVarName2
*/
protected $y;
@@ -71,7 +71,7 @@ class Pum {
protected function test6($x) {
/** @var \Some\Data\VarName $y */
$y = $x['test'];
- /** @var \Some\Data\VarName2 $z */
+ /** @var AliasVarName2 $z */
$z = $x['test2'];
return $y;
}
diff --git a/tests/Drupal/bad/bad_crlf.inc.fixed b/tests/Drupal/bad/bad_crlf.inc.fixed
index ad434228..1fd9757b 100644
--- a/tests/Drupal/bad/bad_crlf.inc.fixed
+++ b/tests/Drupal/bad/bad_crlf.inc.fixed
@@ -5,4 +5,6 @@ namespace Drupal\example\Controller;
/**
* Foo.
*/
-class ExampleController {}
+class ExampleController {
+
+}
diff --git a/tests/Drupal/good/good.php b/tests/Drupal/good/good.php
index f9747220..43d2ebdd 100644
--- a/tests/Drupal/good/good.php
+++ b/tests/Drupal/good/good.php
@@ -1397,17 +1397,6 @@ public function test() {
}
-// Namespaced function call is allowed because PHP 5.5 and lower do not support
-// use statements for functions.
-$default_config = [
- 'verify' => TRUE,
- 'timeout' => 30,
- 'headers' => [
- 'User-Agent' => 'Drupal/' . \Drupal::VERSION . ' (+https://www.drupal.org/) ' . \GuzzleHttp\default_user_agent(),
- ],
- 'handler' => $stack,
-];
-
// camelCase and snake_case variables are allowed.
$snake_case = 1;
$camelCase = 1;
@@ -2065,3 +2054,23 @@ function pdo_weird_return_type($param) {
* Comments are allowed to end in 3 dots...
*/
function comment_test_dots() {}
+
+/**
+ * Executes the page caching before the main kernel takes over the request.
+ */
+class PageCache implements HttpKernelInterface {
+
+ /**
+ * The wrapped HTTP kernel.
+ */
+ protected \Closure $httpKernel;
+
+ /**
+ * The entity for this result.
+ *
+ * @var \Drupal\Core\Entity\EntityInterface
+ */
+ // phpcs:ignore Drupal.NamingConventions.ValidVariableName.LowerCamelName,PSR2.Classes.PropertyDeclaration.Underscore
+ public $_entity = NULL;
+
+}