getTokens(); $previousPointer = TokenHelper::findPreviousExcluding( $phpcsFile, array_merge(TokenHelper::$ineffectiveTokenCodes, TokenHelper::getTypeHintTokenCodes(), [T_NULLABLE]), $variablePointer - 1 ); if ($tokens[$previousPointer]['code'] === T_STATIC) { $previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $previousPointer - 1); } if (in_array($tokens[$previousPointer]['code'], [T_PUBLIC, T_PROTECTED, T_PRIVATE, T_VAR, T_READONLY], true)) { $constructorPointer = TokenHelper::findPrevious($phpcsFile, T_FUNCTION, $previousPointer - 1); if ($constructorPointer === null) { return true; } return $tokens[$constructorPointer]['parenthesis_closer'] < $previousPointer || $promoted; } if ( !array_key_exists('conditions', $tokens[$variablePointer]) || count($tokens[$variablePointer]['conditions']) === 0 ) { return false; } $functionPointer = TokenHelper::findPrevious( $phpcsFile, array_merge(TokenHelper::$functionTokenCodes, [T_SEMICOLON, T_CLOSE_CURLY_BRACKET, T_OPEN_CURLY_BRACKET]), $variablePointer - 1 ); if ( $functionPointer !== null && in_array($tokens[$functionPointer]['code'], TokenHelper::$functionTokenCodes, true) ) { return false; } $conditionCode = array_values($tokens[$variablePointer]['conditions'])[count($tokens[$variablePointer]['conditions']) - 1]; return in_array($conditionCode, Tokens::$ooScopeTokens, true); } public static function findTypeHint(File $phpcsFile, int $propertyPointer): ?TypeHint { $tokens = $phpcsFile->getTokens(); $propertyStartPointer = TokenHelper::findPrevious( $phpcsFile, [T_PRIVATE, T_PROTECTED, T_PUBLIC, T_VAR, T_STATIC, T_READONLY], $propertyPointer - 1 ); $typeHintEndPointer = TokenHelper::findPrevious( $phpcsFile, TokenHelper::getTypeHintTokenCodes(), $propertyPointer - 1, $propertyStartPointer ); if ($typeHintEndPointer === null) { return null; } $typeHintStartPointer = TypeHintHelper::getStartPointer($phpcsFile, $typeHintEndPointer); $previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $typeHintStartPointer - 1, $propertyStartPointer); $nullable = $previousPointer !== null && $tokens[$previousPointer]['code'] === T_NULLABLE; if ($nullable) { $typeHintStartPointer = $previousPointer; } $typeHint = TokenHelper::getContent($phpcsFile, $typeHintStartPointer, $typeHintEndPointer); if (!$nullable) { $nullable = preg_match('~(?:^|\|\s*)null(?:\s*\||$)~i', $typeHint) === 1; } /** @var string $typeHint */ $typeHint = preg_replace('~\s+~', '', $typeHint); return new TypeHint($typeHint, $nullable, $typeHintStartPointer, $typeHintEndPointer); } public static function getFullyQualifiedName(File $phpcsFile, int $propertyPointer): string { $propertyToken = $phpcsFile->getTokens()[$propertyPointer]; $propertyName = $propertyToken['content']; $classPointer = array_reverse(array_keys($propertyToken['conditions']))[0]; if ($phpcsFile->getTokens()[$classPointer]['code'] === T_ANON_CLASS) { return sprintf('class@anonymous::%s', $propertyName); } $name = sprintf('%s%s::%s', NamespaceHelper::NAMESPACE_SEPARATOR, ClassHelper::getName($phpcsFile, $classPointer), $propertyName); $namespace = NamespaceHelper::findCurrentNamespaceName($phpcsFile, $propertyPointer); return $namespace !== null ? sprintf('%s%s%s', NamespaceHelper::NAMESPACE_SEPARATOR, $namespace, $name) : $name; } }