| Current Path : /home/rtorresani/www/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Php/ |
| Current File : //home/rtorresani/www/setup/src/Magento/Setup/Module/I18n/Parser/Adapter/Php/Tokenizer.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Setup\Module\I18n\Parser\Adapter\Php;
/**
* The PHP tokenizer for i18n parser
*/
class Tokenizer
{
/**
* Tokens
*
* @var array
*/
private $_tokens = [];
/**
* Tokens count
*
* @var int
*/
private $_tokensCount;
/**
* Open brackets
*
* @var int
*/
private $_openBrackets;
/**
* Close brackets
*
* @var int
*/
private $_closeBrackets;
/**
* Parse given file
*
* @param string $filePath
* @return void
*/
public function parse($filePath)
{
// phpcs:ignore Magento2.Functions.DiscouragedFunction
$this->_tokens = token_get_all(file_get_contents($filePath));
$this->_tokensCount = count($this->_tokens);
}
/**
* Checks if the next set of tokens is a valid class identifier and it matches passed class name
*
* @param string $className
* @return bool
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function isMatchingClass($className)
{
/*
* 1 - beginning, class identifier can begin either with identifier or with namespace separator
* 2 - after namespace separator, identifier is expected
* 3 - after identifier, namespace separator or open brace is expected
* 4 - ending, tells that class identifier is valid
*/
$state = 1;
$classString = '';
while ($token = $this->getNextRealToken()) {
if ($token->isFullQualifiedName()) {
// In PHP 8.0, it can be already a full name e.g. \Magento\Framework\Phrase.
$classString = $token->getValue();
$state = 3;
} elseif ($token->isNamespaceSeparator() && $state != 2) {
$classString .= $token->getValue();
$state = 2;
} elseif ($token->isIdentifier() && $state != 3) {
$classString .= $token->getValue();
$state = 3;
} elseif ($token->isOpenBrace() && $state == 3) {
$state = 4;
break;
} else {
return false;
}
}
if ($state == 4 && $className == substr($classString, -strlen($className))) {
return true;
}
return false;
}
/**
* Get arguments tokens of function
*
* @return array
*/
public function getFunctionArgumentsTokens()
{
$arguments = [];
try {
$this->_openBrackets = 1;
$this->_closeBrackets = 0;
$argumentNumber = 0;
while (true) {
$token = $this->getNextToken();
if ($token->isSemicolon()) {
break;
}
if ($token->isOpenBrace()) {
$this->_skipInnerArgumentInvoke();
continue;
}
if ($token->isCloseBrace()) {
$this->_closeBrackets++;
}
$arguments[$argumentNumber][] = $token;
if ($token->isComma() && $this->_isInnerArgumentClosed()) {
array_pop($arguments[$argumentNumber]);
$argumentNumber++;
}
if ($this->_openBrackets == $this->_closeBrackets) {
break;
}
}
} catch (\Exception $e) {
return [];
}
return $arguments;
}
/**
* Whenever inner argument closed
*
* @return bool
*/
private function _isInnerArgumentClosed()
{
return $this->_openBrackets - 1 == $this->_closeBrackets;
}
/**
* Skip invoke the inner argument of function
*
* @return void
*/
private function _skipInnerArgumentInvoke()
{
$this->_openBrackets++;
while (!$this->getNextToken()->isCloseBrace()) {
if ($this->getCurrentToken()->isCloseBrace()) {
$this->_closeBrackets++;
}
if ($this->getCurrentToken()->isOpenBrace()) {
$this->_openBrackets++;
}
}
$this->_closeBrackets++;
}
/**
* Get current token
*
* @return \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\Token
*/
public function getCurrentToken()
{
return $this->_createToken(current($this->_tokens));
}
/**
* Get next token
*
* @return bool|\Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\Token
*/
public function getNextToken()
{
return ($token = next($this->_tokens)) ? $this->_createToken($token) : false;
}
/**
* Get next token skipping all whitespaces
*
* @return \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\Token|false
*/
public function getNextRealToken()
{
do {
$token = $this->getNextToken();
} while ($token && $token->isWhitespace());
return $token;
}
/**
* Check if it is end of loop
*
* @return bool
*/
public function isEndOfLoop()
{
return key($this->_tokens) === null;
}
/**
* Create token from array|string
*
* @param array|string $tokenData
* @return \Magento\Setup\Module\I18n\Parser\Adapter\Php\Tokenizer\Token
*/
private function _createToken($tokenData)
{
if (is_array($tokenData)) {
return new Tokenizer\Token($tokenData[0], $tokenData[1], $tokenData[2]);
} else {
return new Tokenizer\Token($tokenData, $tokenData);
}
}
}