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
Namespace
PHP_CodeSniffer\FilesCode
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,
];
}