Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. VariableAnalysisSniff.php

function VariableAnalysisSniff::processVariableAsAssignment

* Process a variable that is being assigned. * * This will record that the variable has been defined within a scope so that * later we can determine if it it unused and we can guarantee that any * future uses of the variable are not using an undefined variable. * * References (on either side of an assignment) behave differently and this * function handles those cases as well. * *

Parameters

File $phpcsFile: * @param int $stackPtr * @param string $varName * @param int $currScope * * @return void

1 call to VariableAnalysisSniff::processVariableAsAssignment()
VariableAnalysisSniff::processVariable in vendor/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php
* Process a normal variable in the code. * * Most importantly, this function determines if the variable use is a "read" * (using the variable for something) or a "write" (an assignment) or, * sometimes, both at once. * …

File

vendor/sirbrillig/phpcs-variable-analysis/VariableAnalysis/Sniffs/CodeAnalysis/VariableAnalysisSniff.php, line 1115

Class

VariableAnalysisSniff

Namespace

VariableAnalysis\Sniffs\CodeAnalysis

Code

protected function processVariableAsAssignment(File $phpcsFile, $stackPtr, $varName, $currScope) {
    Helpers::debug("processVariableAsAssignment: starting for '{$varName}'");
    $assignPtr = Helpers::getNextAssignPointer($phpcsFile, $stackPtr);
    if (!is_int($assignPtr)) {
        return;
    }
    // If the right-hand-side of the assignment to this variable is a reference
    // variable, then this variable is a reference to that one, and as such any
    // assignment to this variable (except another assignment by reference,
    // which would change the binding) has a side effect of changing the
    // referenced variable and therefore should count as both an assignment and
    // a read.
    $tokens = $phpcsFile->getTokens();
    $referencePtr = $phpcsFile->findNext(Tokens::$emptyTokens, $assignPtr + 1, null, true, null, true);
    if (is_int($referencePtr) && $tokens[$referencePtr]['code'] === T_BITWISE_AND) {
        Helpers::debug("processVariableAsAssignment: found reference variable for '{$varName}'");
        $varInfo = $this->getOrCreateVariableInfo($varName, $currScope);
        // If the variable was already declared, but was not yet read, it is
        // unused because we're about to change the binding; that is, unless we
        // are inside a conditional block because in that case the condition may
        // never activate.
        $scopeInfo = $this->getOrCreateScopeInfo($currScope);
        $conditionPointer = Helpers::getClosestConditionPositionIfBeforeOtherConditions($tokens[$referencePtr]['conditions']);
        $lastAssignmentPtr = $varInfo->firstDeclared;
        if (!$conditionPointer && $lastAssignmentPtr) {
            Helpers::debug("processVariableAsAssignment: considering close of scope for '{$varName}' due to reference reassignment");
            $this->processScopeCloseForVariable($phpcsFile, $varInfo, $scopeInfo);
        }
        if ($conditionPointer && $lastAssignmentPtr && $conditionPointer < $lastAssignmentPtr) {
            // We may be inside a condition but the last assignment was also inside this condition.
            Helpers::debug("processVariableAsAssignment: considering close of scope for '{$varName}' due to reference reassignment ignoring recent condition");
            $this->processScopeCloseForVariable($phpcsFile, $varInfo, $scopeInfo);
        }
        if ($conditionPointer && $lastAssignmentPtr && $conditionPointer > $lastAssignmentPtr) {
            Helpers::debug("processVariableAsAssignment: not considering close of scope for '{$varName}' due to reference reassignment because it is conditional");
        }
        // The referenced variable may have a different name, but we don't
        // actually need to mark it as used in this case because the act of this
        // assignment will mark it used on the next token.
        $varInfo->referencedVariableScope = $currScope;
        $this->markVariableDeclaration($varName, ScopeType::LOCAL, null, $stackPtr, $currScope, true);
        // An assignment to a reference is a binding and should not count as
        // initialization since it doesn't change any values.
        $this->markVariableAssignmentWithoutInitialization($varName, $stackPtr, $currScope);
        return;
    }
    Helpers::debug('processVariableAsAssignment: marking as assignment in scope', $currScope);
    $this->markVariableAssignment($varName, $stackPtr, $currScope);
    // If the left-hand-side of the assignment (the variable we are examining)
    // is itself a reference, then that counts as a read as well as a write.
    $varInfo = $this->getOrCreateVariableInfo($varName, $currScope);
    if ($varInfo->isDynamicReference) {
        Helpers::debug('processVariableAsAssignment: also marking as a use because variable is a reference');
        $this->markVariableRead($varName, $stackPtr, $currScope);
    }
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal