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

Breadcrumb

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

function File::getMemberProperties

Returns the visibility and implementation properties of a class member var.

The format of the return value is:

<code> array( 'scope' => string, // Public, private, or protected. 'scope_specified' => boolean, // TRUE if the scope was explicitly specified. 'is_static' => boolean, // TRUE if the static keyword was found. 'is_readonly' => boolean, // TRUE if the readonly keyword was found. 'type' => string, // The type of the var (empty if no type specified). 'type_token' => integer|false, // The stack pointer to the start of the type // or FALSE if there is no type. 'type_end_token' => integer|false, // The stack pointer to the end of the type // or FALSE if there is no type. 'nullable_type' => boolean, // TRUE if the type is preceded by the nullability // operator. ); </code>

Parameters

int $stackPtr The position in the stack of the T_VARIABLE token to: acquire the properties for.

Return value

array

Throws

\PHP_CodeSniffer\Exceptions\RuntimeException If the specified position is not a T_VARIABLE token, or if the position is not a class member variable.

File

vendor/squizlabs/php_codesniffer/src/Files/File.php, line 1857

Class

File

Namespace

PHP_CodeSniffer\Files

Code

public function getMemberProperties($stackPtr) {
    if ($this->tokens[$stackPtr]['code'] !== T_VARIABLE) {
        throw new RuntimeException('$stackPtr must be of type T_VARIABLE');
    }
    $conditions = array_keys($this->tokens[$stackPtr]['conditions']);
    $ptr = array_pop($conditions);
    if (isset($this->tokens[$ptr]) === false || $this->tokens[$ptr]['code'] !== T_CLASS && $this->tokens[$ptr]['code'] !== T_ANON_CLASS && $this->tokens[$ptr]['code'] !== T_TRAIT) {
        if (isset($this->tokens[$ptr]) === true && ($this->tokens[$ptr]['code'] === T_INTERFACE || $this->tokens[$ptr]['code'] === T_ENUM)) {
            // T_VARIABLEs in interfaces/enums can actually be method arguments
            // but they won't be seen as being inside the method because there
            // are no scope openers and closers for abstract methods. If it is in
            // parentheses, we can be pretty sure it is a method argument.
            if (isset($this->tokens[$stackPtr]['nested_parenthesis']) === false || empty($this->tokens[$stackPtr]['nested_parenthesis']) === true) {
                $error = 'Possible parse error: %ss may not include member vars';
                $code = sprintf('Internal.ParseError.%sHasMemberVar', ucfirst($this->tokens[$ptr]['content']));
                $data = [
                    strtolower($this->tokens[$ptr]['content']),
                ];
                $this->addWarning($error, $stackPtr, $code, $data);
                return [];
            }
        }
        else {
            throw new RuntimeException('$stackPtr is not a class member var');
        }
    }
    
    //end if
    // Make sure it's not a method parameter.
    if (empty($this->tokens[$stackPtr]['nested_parenthesis']) === false) {
        $parenthesis = array_keys($this->tokens[$stackPtr]['nested_parenthesis']);
        $deepestOpen = array_pop($parenthesis);
        if ($deepestOpen > $ptr && isset($this->tokens[$deepestOpen]['parenthesis_owner']) === true && $this->tokens[$this->tokens[$deepestOpen]['parenthesis_owner']]['code'] === T_FUNCTION) {
            throw new RuntimeException('$stackPtr is not a class member var');
        }
    }
    $valid = [
        T_PUBLIC => T_PUBLIC,
        T_PRIVATE => T_PRIVATE,
        T_PROTECTED => T_PROTECTED,
        T_STATIC => T_STATIC,
        T_VAR => T_VAR,
        T_READONLY => T_READONLY,
    ];
    $valid += Tokens::$emptyTokens;
    $scope = 'public';
    $scopeSpecified = false;
    $isStatic = false;
    $isReadonly = false;
    $startOfStatement = $this->findPrevious([
        T_SEMICOLON,
        T_OPEN_CURLY_BRACKET,
        T_CLOSE_CURLY_BRACKET,
        T_ATTRIBUTE_END,
    ], $stackPtr - 1);
    for ($i = $startOfStatement + 1; $i < $stackPtr; $i++) {
        if (isset($valid[$this->tokens[$i]['code']]) === false) {
            break;
        }
        switch ($this->tokens[$i]['code']) {
            case T_PUBLIC:
                $scope = 'public';
                $scopeSpecified = true;
                break;
            case T_PRIVATE:
                $scope = 'private';
                $scopeSpecified = true;
                break;
            case T_PROTECTED:
                $scope = 'protected';
                $scopeSpecified = true;
                break;
            case T_STATIC:
                $isStatic = true;
                break;
            case T_READONLY:
                $isReadonly = true;
                break;
        }
    }
    
    //end for
    $type = '';
    $typeToken = false;
    $typeEndToken = false;
    $nullableType = false;
    if ($i < $stackPtr) {
        // We've found a type.
        $valid = [
            T_STRING => T_STRING,
            T_CALLABLE => T_CALLABLE,
            T_SELF => T_SELF,
            T_PARENT => T_PARENT,
            T_FALSE => T_FALSE,
            T_TRUE => T_TRUE,
            T_NULL => T_NULL,
            T_NAMESPACE => T_NAMESPACE,
            T_NS_SEPARATOR => T_NS_SEPARATOR,
            T_TYPE_UNION => T_TYPE_UNION,
            T_TYPE_INTERSECTION => T_TYPE_INTERSECTION,
            T_TYPE_OPEN_PARENTHESIS => T_TYPE_OPEN_PARENTHESIS,
            T_TYPE_CLOSE_PARENTHESIS => T_TYPE_CLOSE_PARENTHESIS,
        ];
        for ($i; $i < $stackPtr; $i++) {
            if ($this->tokens[$i]['code'] === T_VARIABLE) {
                // Hit another variable in a group definition.
                break;
            }
            if ($this->tokens[$i]['code'] === T_NULLABLE) {
                $nullableType = true;
            }
            if (isset($valid[$this->tokens[$i]['code']]) === true) {
                $typeEndToken = $i;
                if ($typeToken === false) {
                    $typeToken = $i;
                }
                $type .= $this->tokens[$i]['content'];
            }
        }
        if ($type !== '' && $nullableType === true) {
            $type = '?' . $type;
        }
    }
    
    //end if
    return [
        'scope' => $scope,
        'scope_specified' => $scopeSpecified,
        'is_static' => $isStatic,
        'is_readonly' => $isReadonly,
        'type' => $type,
        'type_token' => $typeToken,
        'type_end_token' => $typeEndToken,
        'nullable_type' => $nullableType,
    ];
}

API Navigation

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