From 4f10143ae0eab2aab53ff9ca62c1c18009226ed1 Mon Sep 17 00:00:00 2001 From: Nikolaos Dimopoulos Date: Tue, 28 Nov 2023 14:24:37 -0600 Subject: [PATCH] removed more duplicate code --- .../CallUserFuncArrayOptimizer.php | 66 +--- .../FunctionCall/CallUserFuncOptimizer.php | 18 +- .../FunctionCall/CamelizeOptimizer.php | 4 +- .../FunctionCall/UncamelizeOptimizer.php | 63 +--- src/Statements/Let/StaticPropertyAdd.php | 50 ++- src/Statements/Let/StaticPropertySub.php | 332 +----------------- 6 files changed, 66 insertions(+), 467 deletions(-) diff --git a/src/Optimizers/FunctionCall/CallUserFuncArrayOptimizer.php b/src/Optimizers/FunctionCall/CallUserFuncArrayOptimizer.php index aba3da31e..46da59232 100644 --- a/src/Optimizers/FunctionCall/CallUserFuncArrayOptimizer.php +++ b/src/Optimizers/FunctionCall/CallUserFuncArrayOptimizer.php @@ -26,67 +26,19 @@ * * Optimizer for 'call_user_func_array' */ -class CallUserFuncArrayOptimizer extends OptimizerAbstract +class CallUserFuncArrayOptimizer extends CallUserFuncOptimizer { + protected string $zephirMethod = 'ZEPHIR_CALL_USER_FUNC_ARRAY'; + /** - * @param array $expression - * @param Call $call - * @param CompilationContext $context + * @param string $symbol + * @param array $resolvedParams * - * @return bool|CompiledExpression|mixed + * @return string */ - public function optimize(array $expression, Call $call, CompilationContext $context) + protected function getOutput(string $symbol, array $resolvedParams): string { - if (!isset($expression['parameters'])) { - return false; - } - - if (2 != count($expression['parameters'])) { - return false; - } - - /* - * Process the expected symbol to be returned - */ - $call->processExpectedReturn($context); - - $symbolVariable = $call->getSymbolVariable(true, $context); - if ($symbolVariable) { - if (!$symbolVariable->isVariable()) { - throw new CompilerException( - 'Returned values by functions can only be assigned to variant variables', - $expression - ); - } - } else { - $symbolVariable = $context->symbolTable->addTemp('variable', $context); - $symbolVariable->initVariant($context); - } - - /* - * Add the last call status to the current symbol table - */ - $call->addCallStatusFlag($context); - - $resolvedParams = $call->getReadOnlyResolvedParams($expression['parameters'], $context, $expression); - - $context->headersManager->add('kernel/fcall'); - - /* - * Add the last call status to the current symbol table - */ - $call->addCallStatusFlag($context); - - if ($call->mustInitSymbolVariable()) { - $symbolVariable->initVariant($context); - } - - $symbol = $context->backend->getVariableCode($symbolVariable); - $context->codePrinter->output( - 'ZEPHIR_CALL_USER_FUNC_ARRAY(' . $symbol . ', ' . $resolvedParams[0] . ', ' . $resolvedParams[1] . ');' - ); - $call->addCallStatusOrJump($context); - - return new CompiledExpression('variable', $symbolVariable->getName(), $expression); + return $this->zephirMethod + . '(' . $symbol . ', ' . $resolvedParams[0] . ', ' . $resolvedParams[1] . ');'; } } diff --git a/src/Optimizers/FunctionCall/CallUserFuncOptimizer.php b/src/Optimizers/FunctionCall/CallUserFuncOptimizer.php index 27df94855..d3cb88c8b 100644 --- a/src/Optimizers/FunctionCall/CallUserFuncOptimizer.php +++ b/src/Optimizers/FunctionCall/CallUserFuncOptimizer.php @@ -28,6 +28,8 @@ */ class CallUserFuncOptimizer extends OptimizerAbstract { + protected string $zephirMethod = 'ZEPHIR_CALL_USER_FUNC'; + /** * @param array $expression * @param Call $call @@ -82,9 +84,23 @@ public function optimize(array $expression, Call $call, CompilationContext $cont } $symbol = $context->backend->getVariableCode($symbolVariable); - $context->codePrinter->output('ZEPHIR_CALL_USER_FUNC(' . $symbol . ', ' . $resolvedParams[0] . ');'); + $context->codePrinter->output( + $this->getOutput($symbol, $resolvedParams) + ); $call->addCallStatusOrJump($context); return new CompiledExpression('variable', $symbolVariable->getName(), $expression); } + + /** + * @param string $symbol + * @param array $resolvedParams + * + * @return string + */ + protected function getOutput(string $symbol, array $resolvedParams): string + { + return $this->zephirMethod + . '(' . $symbol . ', ' . $resolvedParams[0] . ');'; + } } diff --git a/src/Optimizers/FunctionCall/CamelizeOptimizer.php b/src/Optimizers/FunctionCall/CamelizeOptimizer.php index 38b04e5b7..3cd8fbc6c 100644 --- a/src/Optimizers/FunctionCall/CamelizeOptimizer.php +++ b/src/Optimizers/FunctionCall/CamelizeOptimizer.php @@ -28,6 +28,8 @@ */ class CamelizeOptimizer extends OptimizerAbstract { + protected string $zephirMethod = 'zephir_camelize'; + /** * @param array $expression * @param Call $call @@ -83,7 +85,7 @@ public function optimize(array $expression, Call $call, CompilationContext $cont $symbol = $context->backend->getVariableCode($symbolVariable); $context->codePrinter->output( - 'zephir_camelize(' . $symbol . ', ' . $resolvedParams[0] . ', ' . $delimiter . ' );' + $this->zephirMethod . '(' . $symbol . ', ' . $resolvedParams[0] . ', ' . $delimiter . ' );' ); return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression); diff --git a/src/Optimizers/FunctionCall/UncamelizeOptimizer.php b/src/Optimizers/FunctionCall/UncamelizeOptimizer.php index 5d67787e5..ca0ce3ce7 100644 --- a/src/Optimizers/FunctionCall/UncamelizeOptimizer.php +++ b/src/Optimizers/FunctionCall/UncamelizeOptimizer.php @@ -26,66 +26,7 @@ * * Optimizes calls to 'uncamelize' using internal function */ -class UncamelizeOptimizer extends OptimizerAbstract +class UncamelizeOptimizer extends CamelizeOptimizer { - /** - * @param array $expression - * @param Call $call - * @param CompilationContext $context - * - * @return bool|CompiledExpression|mixed - * - * @throws CompilerException - */ - public function optimize(array $expression, Call $call, CompilationContext $context) - { - if (!isset($expression['parameters'])) { - return false; - } - - if (count($expression['parameters']) < 1 || count($expression['parameters']) > 2) { - throw new CompilerException("'uncamelize' only accepts one or two parameters"); - } - - $delimiter = 'NULL '; - if (2 == count($expression['parameters'])) { - if ('null' == $expression['parameters'][1]['parameter']['type']) { - unset($expression['parameters'][1]); - } - } - - /* - * Process the expected symbol to be returned - */ - $call->processExpectedReturn($context); - - $symbolVariable = $call->getSymbolVariable(true, $context); - if ($symbolVariable->isNotVariableAndString()) { - throw new CompilerException( - 'Returned values by functions can only be assigned to variant variables', - $expression - ); - } - - $context->headersManager->add('kernel/string'); - - $symbolVariable->setDynamicTypes('string'); - - $resolvedParams = $call->getReadOnlyResolvedParams($expression['parameters'], $context, $expression); - - if (isset($resolvedParams[1])) { - $delimiter = $resolvedParams[1]; - } - - if ($call->mustInitSymbolVariable()) { - $symbolVariable->initVariant($context); - } - - $symbol = $context->backend->getVariableCode($symbolVariable); - $context->codePrinter->output( - 'zephir_uncamelize(' . $symbol . ', ' . $resolvedParams[0] . ', ' . $delimiter . ' );' - ); - - return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression); - } + protected string $zephirMethod = 'zephir_uncamelize'; } diff --git a/src/Statements/Let/StaticPropertyAdd.php b/src/Statements/Let/StaticPropertyAdd.php index 67a18b2b7..8f61cacac 100644 --- a/src/Statements/Let/StaticPropertyAdd.php +++ b/src/Statements/Let/StaticPropertyAdd.php @@ -26,6 +26,8 @@ */ class StaticPropertyAdd { + protected string $methodName = 'addStaticProperty'; + /** * Compiles ClassName::foo = {expr}. * @@ -46,6 +48,7 @@ public function assignStatic( array $statement ): void { $classDefinition = $compilationContext->classLookup($className); + $methodName = $this->methodName; if (!$propertyDefinition = $classDefinition->getProperty($property)) { throw new CompilerException( @@ -93,7 +96,12 @@ public function assignStatic( switch ($resolvedExpr->getType()) { case 'null': - $compilationContext->backend->updateStaticProperty($classEntry, $property, 'null', $compilationContext); + $compilationContext->backend->updateStaticProperty( + $classEntry, + $property, + 'null', + $compilationContext + ); break; case 'int': @@ -109,7 +117,7 @@ public function assignStatic( $resolvedExpr->getBooleanCode(), $compilationContext ); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -132,7 +140,7 @@ public function assignStatic( '\'' . $resolvedExpr->getCode() . '\'', $compilationContext ); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -154,7 +162,7 @@ public function assignStatic( $resolvedExpr->getCode(), $compilationContext ); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -187,7 +195,7 @@ public function assignStatic( $tempVariable->setIdle(true); } - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -197,7 +205,7 @@ public function assignStatic( case 'bool': if ('1' == $resolvedExpr->getBooleanCode()) { - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, 'true', @@ -205,7 +213,7 @@ public function assignStatic( ); } else { if ('0' == $resolvedExpr->getBooleanCode()) { - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, 'false', @@ -214,7 +222,7 @@ public function assignStatic( } else { $codePrinter->output('if (' . $resolvedExpr->getBooleanCode() . ') {'); $codePrinter->increaseLevel(); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, 'true', @@ -223,7 +231,7 @@ public function assignStatic( $codePrinter->decreaseLevel(); $codePrinter->output('} else {'); $codePrinter->increaseLevel(); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, 'false', @@ -242,7 +250,7 @@ public function assignStatic( true ); $compilationContext->backend->initArray($tempVariable, $compilationContext); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -254,7 +262,7 @@ public function assignStatic( break; case 'array': - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $resolvedExpr, @@ -282,8 +290,12 @@ public function assignStatic( true ); - $compilationContext->backend->assignLong($tempVariable, $variableVariable, $compilationContext); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->assignLong( + $tempVariable, + $variableVariable, + $compilationContext + ); + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -307,7 +319,7 @@ public function assignStatic( $variableVariable, $compilationContext ); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -325,8 +337,12 @@ public function assignStatic( $compilationContext, true ); - $compilationContext->backend->assignBool($tempVariable, $variableVariable, $compilationContext); - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->assignBool( + $tempVariable, + $variableVariable, + $compilationContext + ); + $compilationContext->backend->$methodName( $classEntry, $property, $tempVariable, @@ -337,7 +353,7 @@ public function assignStatic( } break; default: - $compilationContext->backend->addStaticProperty( + $compilationContext->backend->$methodName( $classEntry, $property, $variableVariable, diff --git a/src/Statements/Let/StaticPropertySub.php b/src/Statements/Let/StaticPropertySub.php index afb0b8afa..4521d9762 100644 --- a/src/Statements/Let/StaticPropertySub.php +++ b/src/Statements/Let/StaticPropertySub.php @@ -26,335 +26,7 @@ * * Updates static properties */ -class StaticPropertySub +class StaticPropertySub extends StaticPropertyAdd { - /** - * Compiles ClassName::foo = {expr}. - * - * @param string $className - * @param string $property - * @param CompiledExpression $resolvedExpr - * @param CompilationContext $compilationContext - * @param array $statement - * - * @throws CompilerException - * @throws IllegalOperationException - */ - public function assignStatic( - string $className, - string $property, - CompiledExpression $resolvedExpr, - CompilationContext $compilationContext, - array $statement - ): void { - $classDefinition = $compilationContext->classLookup($className); - - if (!$propertyDefinition = $classDefinition->getProperty($property)) { - throw new CompilerException( - sprintf( - "Class '%s' does not have a property called: '%s", - $classDefinition->getCompleteName(), - $property - ), - $statement - ); - } - - if (!$propertyDefinition->isStatic()) { - throw new CompilerException( - sprintf( - "Cannot access non-static property '%s::%s", - $classDefinition->getCompleteName(), - $property - ), - $statement - ); - } - - if ($propertyDefinition->isPrivate()) { - if ($classDefinition->getCompleteName() != $compilationContext->classDefinition->getCompleteName()) { - throw new CompilerException( - sprintf( - "Cannot access private static property '%s::%s out of its declaring context", - $classDefinition->getCompleteName(), - $property - ), - $statement - ); - } - } - - $codePrinter = $compilationContext->codePrinter; - $compilationContext->headersManager->add('kernel/object'); - - try { - $classEntry = $classDefinition->getClassEntry($compilationContext); - } catch (Exception $e) { - throw new CompilerException($e->getMessage(), $statement, $e->getCode(), $e); - } - - switch ($resolvedExpr->getType()) { - case 'null': - $compilationContext->backend->updateStaticProperty($classEntry, $property, 'null', $compilationContext); - break; - - case 'int': - case 'uint': - case 'long': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - $compilationContext->backend->assignLong( - $tempVariable, - $resolvedExpr->getBooleanCode(), - $compilationContext - ); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - - case 'char': - case 'uchar': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - $compilationContext->backend->assignLong( - $tempVariable, - '\'' . $resolvedExpr->getCode() . '\'', - $compilationContext - ); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - - case 'double': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - $compilationContext->backend->assignDouble( - $tempVariable, - $resolvedExpr->getCode(), - $compilationContext - ); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - - case 'string': - $tempVariable = $compilationContext->symbolTable->getTempVariableForWrite( - 'variable', - $compilationContext, - true - ); - $tempVariable->initVariant($compilationContext); - - if ($resolvedExpr->getCode()) { - $compilationContext->backend->assignString( - $tempVariable, - $resolvedExpr->getCode(), - $compilationContext - ); - } else { - $codePrinter->output('ZVAL_EMPTY_STRING(' . $tempVariable->getName() . ');'); - } - - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - break; - - case 'bool': - if ('1' == $resolvedExpr->getBooleanCode()) { - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - 'true', - $compilationContext - ); - } else { - if ('0' == $resolvedExpr->getBooleanCode()) { - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - 'false', - $compilationContext - ); - } else { - $codePrinter->output('if (' . $resolvedExpr->getBooleanCode() . ') {'); - $codePrinter->increaseLevel(); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - 'true', - $compilationContext - ); - $codePrinter->decreaseLevel(); - $codePrinter->output('} else {'); - $codePrinter->increaseLevel(); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - 'false', - $compilationContext - ); - $codePrinter->decreaseLevel(); - $codePrinter->output('}'); - } - } - break; - - case 'empty-array': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - $compilationContext->backend->initArray($tempVariable, $compilationContext); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - - case 'array': - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $resolvedExpr, - $compilationContext - ); - break; - - case 'variable': - $variableVariable = $compilationContext->symbolTable->getVariableForRead( - $resolvedExpr->getCode(), - $compilationContext, - $statement - ); - - switch ($variableVariable->getType()) { - case 'int': - case 'uint': - case 'long': - case 'ulong': - case 'char': - case 'uchar': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - - $compilationContext->backend->assignLong($tempVariable, $variableVariable, $compilationContext); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - - case 'double': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - - $compilationContext->backend->assignDouble( - $tempVariable, - $variableVariable, - $compilationContext - ); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - - case 'bool': - $tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable( - 'variable', - $compilationContext, - true - ); - $compilationContext->backend->assignBool($tempVariable, $variableVariable, $compilationContext); - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $tempVariable, - $compilationContext - ); - if ($tempVariable->isTemporal()) { - $tempVariable->setIdle(true); - } - break; - default: - $compilationContext->backend->subStaticProperty( - $classEntry, - $property, - $variableVariable, - $compilationContext - ); - if ($variableVariable->isTemporal()) { - $variableVariable->setIdle(true); - } - break; - } - - break; - - default: - throw new CompilerException('Unknown type ' . $resolvedExpr->getType(), $statement); - } - } + protected string $methodName = 'subStaticProperty'; }