class DisallowImplicitArrayCreationSniff
Hierarchy
- class \SlevomatCodingStandard\Sniffs\Arrays\DisallowImplicitArrayCreationSniff implements \PHP_CodeSniffer\Sniffs\Sniff
Expanded class hierarchy of DisallowImplicitArrayCreationSniff
File
-
vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ Arrays/ DisallowImplicitArrayCreationSniff.php, line 31
Namespace
SlevomatCodingStandard\Sniffs\ArraysView source
class DisallowImplicitArrayCreationSniff implements Sniff {
public const CODE_IMPLICIT_ARRAY_CREATION_USED = 'ImplicitArrayCreationUsed';
/**
* @return array<int, (int|string)>
*/
public function register() : array {
return [
T_OPEN_SQUARE_BRACKET,
];
}
/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
* @param int $bracketOpenerPointer
*/
public function process(File $phpcsFile, $bracketOpenerPointer) : void {
$tokens = $phpcsFile->getTokens();
$assignmentPointer = TokenHelper::findNextEffective($phpcsFile, $tokens[$bracketOpenerPointer]['bracket_closer'] + 1);
if ($tokens[$assignmentPointer]['code'] !== T_EQUAL) {
return;
}
/** @var int $variablePointer */
$variablePointer = TokenHelper::findPreviousEffective($phpcsFile, $bracketOpenerPointer - 1);
if ($tokens[$variablePointer]['code'] !== T_VARIABLE) {
return;
}
if (in_array($tokens[$variablePointer]['content'], [
'$GLOBALS',
'$_SERVER',
'$_REQUEST',
'$_POST',
'$_GET',
'$_FILES',
'$_ENV',
'$_COOKIE',
'$_SESSION',
'$this',
], true)) {
return;
}
$pointerBeforeVariable = TokenHelper::findPreviousEffective($phpcsFile, $variablePointer - 1);
if (in_array($tokens[$pointerBeforeVariable]['code'], [
T_OBJECT_OPERATOR,
T_DOUBLE_COLON,
], true)) {
return;
}
$scopeOwnerPointer = null;
foreach (array_reverse($tokens[$variablePointer]['conditions'], true) as $conditionPointer => $conditionTokenCode) {
if (!in_array($conditionTokenCode, TokenHelper::$functionTokenCodes, true)) {
continue;
}
$scopeOwnerPointer = $conditionPointer;
break;
}
if ($scopeOwnerPointer === null) {
$scopeOwnerPointer = TokenHelper::findPrevious($phpcsFile, T_OPEN_TAG, $variablePointer - 1);
}
$scopeOpenerPointer = $tokens[$scopeOwnerPointer]['code'] === T_OPEN_TAG ? $scopeOwnerPointer : $tokens[$scopeOwnerPointer]['scope_opener'];
$scopeCloserPointer = $tokens[$scopeOwnerPointer]['code'] === T_OPEN_TAG ? count($tokens) - 1 : $tokens[$scopeOwnerPointer]['scope_closer'];
if (in_array($tokens[$scopeOwnerPointer]['code'], TokenHelper::$functionTokenCodes, true)) {
if ($this->isParameter($phpcsFile, $scopeOwnerPointer, $variablePointer)) {
return;
}
if ($tokens[$scopeOwnerPointer]['code'] === T_CLOSURE && $this->isInheritedVariable($phpcsFile, $scopeOwnerPointer, $variablePointer)) {
return;
}
}
if ($this->hasExplicitCreation($phpcsFile, $scopeOpenerPointer, $scopeCloserPointer, $variablePointer)) {
return;
}
$phpcsFile->addError('Implicit array creation is disallowed.', $variablePointer, self::CODE_IMPLICIT_ARRAY_CREATION_USED);
}
private function isParameter(File $phpcsFile, int $functionPointer, int $variablePointer) : bool {
$tokens = $phpcsFile->getTokens();
$variableName = $tokens[$variablePointer]['content'];
$parameterPointer = TokenHelper::findNextContent($phpcsFile, T_VARIABLE, $variableName, $tokens[$functionPointer]['parenthesis_opener'] + 1, $tokens[$functionPointer]['parenthesis_closer']);
return $parameterPointer !== null;
}
private function isInheritedVariable(File $phpcsFile, int $closurePointer, int $variablePointer) : bool {
$tokens = $phpcsFile->getTokens();
$variableName = $tokens[$variablePointer]['content'];
$usePointer = TokenHelper::findNext($phpcsFile, T_USE, $tokens[$closurePointer]['parenthesis_closer'] + 1, $tokens[$closurePointer]['scope_opener']);
if ($usePointer === null) {
return false;
}
$parenthesisOpenerPointer = TokenHelper::findNextEffective($phpcsFile, $usePointer + 1);
$inheritedVariablePointer = TokenHelper::findNextContent($phpcsFile, T_VARIABLE, $variableName, $parenthesisOpenerPointer + 1, $tokens[$parenthesisOpenerPointer]['parenthesis_closer']);
return $inheritedVariablePointer !== null;
}
private function hasExplicitCreation(File $phpcsFile, int $scopeOpenerPointer, int $scopeCloserPointer, int $variablePointer) : bool {
$tokens = $phpcsFile->getTokens();
$variableName = $tokens[$variablePointer]['content'];
for ($i = $scopeOpenerPointer + 1; $i < $variablePointer; $i++) {
if ($tokens[$i]['code'] !== T_VARIABLE) {
continue;
}
if ($tokens[$i]['content'] !== $variableName) {
continue;
}
if (!ScopeHelper::isInSameScope($phpcsFile, $variablePointer, $i)) {
continue;
}
$assignmentPointer = TokenHelper::findNextEffective($phpcsFile, $i + 1);
if ($tokens[$assignmentPointer]['code'] === T_EQUAL) {
return true;
}
$staticPointer = TokenHelper::findPreviousEffective($phpcsFile, $i - 1);
if ($tokens[$staticPointer]['code'] === T_STATIC) {
return true;
}
if ($this->isCreatedInForeach($phpcsFile, $i, $scopeCloserPointer)) {
return true;
}
if ($this->isCreatedInList($phpcsFile, $i, $scopeOpenerPointer)) {
return true;
}
if ($this->isCreatedByReferencedParameterInFunctionCall($phpcsFile, $i, $scopeOpenerPointer)) {
return true;
}
if ($this->isImportedUsingGlobalStatement($phpcsFile, $i)) {
return true;
}
}
return false;
}
private function isCreatedInList(File $phpcsFile, int $variablePointer, int $scopeOpenerPointer) : bool {
$tokens = $phpcsFile->getTokens();
$parenthesisOpenerPointer = TokenHelper::findPrevious($phpcsFile, [
T_OPEN_PARENTHESIS,
T_OPEN_SHORT_ARRAY,
T_OPEN_SQUARE_BRACKET,
], $variablePointer - 1, $scopeOpenerPointer);
if ($parenthesisOpenerPointer === null) {
return false;
}
if ($tokens[$parenthesisOpenerPointer]['code'] === T_OPEN_PARENTHESIS) {
if ($tokens[$parenthesisOpenerPointer]['parenthesis_closer'] < $variablePointer) {
return false;
}
$pointerBeforeParenthesisOpener = TokenHelper::findPreviousEffective($phpcsFile, $parenthesisOpenerPointer - 1);
return $tokens[$pointerBeforeParenthesisOpener]['code'] === T_LIST;
}
return $tokens[$parenthesisOpenerPointer]['bracket_closer'] > $variablePointer;
}
private function isCreatedInForeach(File $phpcsFile, int $variablePointer, int $scopeCloserPointer) : bool {
$tokens = $phpcsFile->getTokens();
$parenthesisCloserPointer = TokenHelper::findNext($phpcsFile, T_CLOSE_PARENTHESIS, $variablePointer + 1, $scopeCloserPointer);
return $parenthesisCloserPointer !== null && array_key_exists('parenthesis_owner', $tokens[$parenthesisCloserPointer]) && $tokens[$tokens[$parenthesisCloserPointer]['parenthesis_owner']]['code'] === T_FOREACH && $tokens[$parenthesisCloserPointer]['parenthesis_opener'] < $variablePointer;
}
private function isCreatedByReferencedParameterInFunctionCall(File $phpcsFile, int $variablePointer, int $scopeOpenerPointer) : bool {
$tokens = $phpcsFile->getTokens();
$parenthesisOpenerPointer = TokenHelper::findPrevious($phpcsFile, T_OPEN_PARENTHESIS, $variablePointer - 1, $scopeOpenerPointer);
if ($parenthesisOpenerPointer === null || $tokens[$parenthesisOpenerPointer]['parenthesis_closer'] < $variablePointer) {
return false;
}
$pointerBeforeParenthesisOpener = TokenHelper::findPreviousEffective($phpcsFile, $parenthesisOpenerPointer - 1);
return $tokens[$pointerBeforeParenthesisOpener]['code'] === T_STRING;
}
private function isImportedUsingGlobalStatement(File $phpcsFile, int $variablePointer) : bool {
$tokens = $phpcsFile->getTokens();
$startOfStatement = $phpcsFile->findStartOfStatement($variablePointer, T_COMMA);
return $tokens[$startOfStatement]['code'] === T_GLOBAL;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
DisallowImplicitArrayCreationSniff::CODE_IMPLICIT_ARRAY_CREATION_USED | public | constant | ||
DisallowImplicitArrayCreationSniff::hasExplicitCreation | private | function | ||
DisallowImplicitArrayCreationSniff::isCreatedByReferencedParameterInFunctionCall | private | function | ||
DisallowImplicitArrayCreationSniff::isCreatedInForeach | private | function | ||
DisallowImplicitArrayCreationSniff::isCreatedInList | private | function | ||
DisallowImplicitArrayCreationSniff::isImportedUsingGlobalStatement | private | function | ||
DisallowImplicitArrayCreationSniff::isInheritedVariable | private | function | ||
DisallowImplicitArrayCreationSniff::isParameter | private | function | ||
DisallowImplicitArrayCreationSniff::process | public | function | * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * |
Overrides Sniff::process |
DisallowImplicitArrayCreationSniff::register | public | function | * | Overrides Sniff::register |