本文整理汇总了PHP中Zephir\Expression::setExpectReturn方法的典型用法代码示例。如果您正苦于以下问题:PHP Expression::setExpectReturn方法的具体用法?PHP Expression::setExpectReturn怎么用?PHP Expression::setExpectReturn使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Zephir\Expression
的用法示例。
在下文中一共展示了Expression::setExpectReturn方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: compile
/**
* @param array $expression
* @param CompilationContext $compilationContext
* @return CompiledExpression
* @throws CompilerException
*/
public function compile(array $expression, CompilationContext $compilationContext)
{
$expr = new Expression($expression['left']);
$expr->setReadOnly(true);
$expr->setExpectReturn(true);
$exprPath = $expr->compile($compilationContext);
if ($exprPath->getType() == 'variable') {
$exprVariable = $compilationContext->symbolTable->getVariableForRead($exprPath->getCode(), $compilationContext, $expression);
if ($exprVariable->getType() == 'variable') {
if ($exprVariable->hasDifferentDynamicType(array('undefined', 'string'))) {
$compilationContext->logger->warning('Possible attempt to use invalid type as path in "require" operator', 'non-valid-require', $expression);
}
}
}
$symbolVariable = false;
if ($this->isExpecting()) {
$symbolVariable = $compilationContext->symbolTable->getTempVariableForObserveOrNullify('variable', $compilationContext, $expression);
}
$compilationContext->headersManager->add('kernel/memory');
$compilationContext->headersManager->add('kernel/require');
$codePrinter = $compilationContext->codePrinter;
if ($symbolVariable) {
$codePrinter->output('ZEPHIR_OBSERVE_OR_NULLIFY_PPZV(&' . $symbolVariable->getName() . ');');
$codePrinter->output('if (zephir_require_zval_ret(&' . $symbolVariable->getName() . ', ' . $exprPath->getCode() . ' TSRMLS_CC) == FAILURE) {');
} else {
$codePrinter->output('if (zephir_require_zval(' . $exprPath->getCode() . ' TSRMLS_CC) == FAILURE) {');
}
$codePrinter->output("\t" . 'RETURN_MM_NULL();');
$codePrinter->output('}');
if ($symbolVariable) {
return new CompiledExpression('variable', $symbolVariable->getName(), $expression);
}
return new CompiledExpression('null', null, $expression);
}
示例2: compile
/**
* @param CompilationContext $compilationContext
* @throws CompilerException
*/
public function compile(CompilationContext $compilationContext)
{
$expression = array('type' => 'require', 'left' => $this->_statement['expr'], 'file' => $this->_statement['file'], 'line' => $this->_statement['line'], 'char' => $this->_statement['char']);
$expr = new Expression($expression);
$expr->setExpectReturn(false, null);
$expr->compile($compilationContext);
}
示例3: compile
/**
* @param array $expression
* @param CompilationContext $compilationContext
* @return CompiledExpression
* @throws CompilerException
*/
public function compile(array $expression, CompilationContext $compilationContext)
{
$compilationContext->headersManager->add('kernel/object');
$exprVariable = new Expression($expression['left']);
$exprVariable->setReadOnly(true);
$exprVariable->setExpectReturn(true);
$exprCompiledVariable = $exprVariable->compile($compilationContext);
if ($exprCompiledVariable->getType() != 'variable') {
throw new CompilerException("Expression type: " . $exprCompiledVariable->getType() . " cannot be used as array", $expression);
}
$clonedVariable = $compilationContext->symbolTable->getVariableForRead($exprCompiledVariable->getCode(), $compilationContext, $expression);
if ($clonedVariable->getType() != 'variable') {
throw new CompilerException("Variable type: " . $exprVariable->getType() . " cannot be cloned");
}
if ($clonedVariable->hasDifferentDynamicType(array('undefined', 'object', 'null'))) {
$compilationContext->logger->warning('Possible attempt to use non array in "clone" operator', 'non-valid-clone', $expression);
}
$symbolVariable = $this->getExpected($compilationContext, $expression);
if (!$symbolVariable->isVariable()) {
throw new CompilerException("Objects can only be cloned into dynamic variables", $expression);
}
$symbolVariable->setDynamicTypes('object');
$symbolVariable->setIsInitialized(true, $compilationContext, $expression);
/* Inherit the dynamic type data from the cloned object */
$symbolVariable->setDynamicTypes($clonedVariable->getDynamicTypes());
$symbolVariable->setClassTypes($clonedVariable->getClassTypes());
$compilationContext->codePrinter->output('if (zephir_clone(' . $symbolVariable->getName() . ', ' . $clonedVariable->getName() . ' TSRMLS_CC) == FAILURE) {');
$compilationContext->codePrinter->output("\t" . 'RETURN_MM();');
$compilationContext->codePrinter->output('}');
return new CompiledExpression('variable', $symbolVariable->getName(), $expression);
}
示例4: compile
//.........这里部分代码省略.........
break;
case 'for':
$forStatement = new ForStatement($statement);
$forStatement->compile($compilationContext);
break;
case 'return':
$returnStatement = new ReturnStatement($statement);
$returnStatement->compile($compilationContext);
$this->_unreachable = true;
break;
case 'require':
$requireStatement = new RequireStatement($statement);
$requireStatement->compile($compilationContext);
break;
case 'loop':
$loopStatement = new LoopStatement($statement);
$loopStatement->compile($compilationContext);
break;
case 'break':
$breakStatement = new BreakStatement($statement);
$breakStatement->compile($compilationContext);
$this->_unreachable = true;
break;
case 'continue':
$continueStatement = new ContinueStatement($statement);
$continueStatement->compile($compilationContext);
$this->_unreachable = true;
break;
case 'unset':
$unsetStatement = new UnsetStatement($statement);
$unsetStatement->compile($compilationContext);
break;
case 'throw':
$throwStatement = new ThrowStatement($statement);
$throwStatement->compile($compilationContext);
$this->_unreachable = true;
break;
case 'try-catch':
$throwStatement = new TryCatchStatement($statement);
$throwStatement->compile($compilationContext);
$this->_unreachable = false;
break;
case 'fetch':
$expr = new Expression($statement['expr']);
$expr->setExpectReturn(false);
$compiledExpression = $expr->compile($compilationContext);
$compilationContext->codePrinter->output($compiledExpression->getCode() . ';');
break;
case 'mcall':
$methodCall = new MethodCall();
$expr = new Expression($statement['expr']);
$expr->setExpectReturn(false);
$methodCall->compile($expr, $compilationContext);
break;
case 'fcall':
$functionCall = new FunctionCall();
$expr = new Expression($statement['expr']);
$expr->setExpectReturn(false);
$compiledExpression = $functionCall->compile($expr, $compilationContext);
switch ($compiledExpression->getType()) {
case 'int':
case 'double':
case 'uint':
case 'long':
case 'ulong':
case 'char':
case 'uchar':
case 'bool':
$compilationContext->codePrinter->output($compiledExpression->getCode() . ';');
break;
}
break;
case 'scall':
$methodCall = new StaticCall();
$expr = new Expression($statement['expr']);
$expr->setExpectReturn(false);
$methodCall->compile($expr, $compilationContext);
break;
case 'cblock':
$compilationContext->codePrinter->output($statement['value']);
break;
case 'empty':
break;
default:
throw new Exception('Unsupported statement: ' . $statement['type']);
}
if ($statement['type'] != 'comment') {
$this->_lastStatement = $statement;
}
}
/**
* Traverses temporal variables created in a specific branch
* marking them as idle
*/
$compilationContext->symbolTable->markTemporalVariablesIdle($compilationContext);
$compilationContext->branchManager->removeBranch($currentBranch);
$compilationContext->currentBranch--;
$compilationContext->codePrinter->decreaseLevel();
return $currentBranch;
}
示例5: compile
//.........这里部分代码省略.........
break;
case 'mul':
$compilableExpression = new MulOperator();
break;
case 'div':
$compilableExpression = new DivOperator();
break;
case 'mod':
$compilableExpression = new ModOperator();
break;
case 'and':
$compilableExpression = new AndOperator();
break;
case 'or':
$compilableExpression = new OrOperator();
break;
case 'bitwise_and':
$compilableExpression = new BitwiseAndOperator();
break;
case 'bitwise_or':
$compilableExpression = new BitwiseOrOperator();
break;
case 'bitwise_xor':
$compilableExpression = new BitwiseXorOperator();
break;
case 'bitwise_shiftleft':
$compilableExpression = new ShiftLeftOperator();
break;
case 'bitwise_shiftright':
$compilableExpression = new ShiftRightOperator();
break;
case 'concat':
$expr = new ConcatOperator();
$expr->setExpectReturn($this->_expecting, $this->_expectingVariable);
return $expr->compile($expression, $compilationContext);
case 'irange':
$compilableExpression = new RangeInclusiveOperator();
break;
case 'erange':
$compilableExpression = new RangeExclusiveOperator();
break;
case 'list':
if ($expression['left']['type'] == 'list') {
$compilationContext->logger->warning("Unnecessary extra parentheses", "extra-parentheses", $expression);
}
$numberPrints = $compilationContext->codePrinter->getNumberPrints();
$expr = new Expression($expression['left']);
$expr->setExpectReturn($this->_expecting, $this->_expectingVariable);
$resolved = $expr->compile($compilationContext);
if ($compilationContext->codePrinter->getNumberPrints() - $numberPrints <= 1) {
if (strpos($resolved->getCode(), ' ') !== false) {
return new CompiledExpression($resolved->getType(), '(' . $resolved->getCode() . ')', $expression);
}
}
return $resolved;
case 'cast':
$compilableExpression = new CastOperator();
break;
case 'type-hint':
return $this->compileTypeHint($expression, $compilationContext);
case 'instanceof':
$compilableExpression = new InstanceOfOperator();
break;
case 'clone':
$compilableExpression = new CloneOperator();
break;
示例6: assignDefaultValue
/**
* Assigns a default value
*
* @param array $parameter
* @param CompilationContext $compilationContext
* @return string
* @throws CompilerException
*/
public function assignDefaultValue(array $parameter, CompilationContext $compilationContext)
{
if (isset($parameter['data-type'])) {
$dataType = $parameter['data-type'];
} else {
$dataType = 'variable';
}
/**
* Class-Hinted parameters only can be null?
*/
if (isset($parameter['cast'])) {
if ($parameter['default']['type'] != 'null') {
throw new CompilerException('Class-Hinted parameters only can have "null" as default parameter', $parameter);
}
}
$oldCodePrinter = $compilationContext->codePrinter;
$codePrinter = new CodePrinter();
$codePrinter->increaseLevel();
$codePrinter->increaseLevel();
$compilationContext->codePrinter = $codePrinter;
$paramVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext);
/**
* @todo Refactoring this place, move to one - static-constant-access
*/
switch ($dataType) {
case 'int':
case 'uint':
case 'long':
case 'ulong':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'int') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(int)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$codePrinter->output($parameter['name'] . ' = 0;');
break;
case 'int':
case 'uint':
case 'long':
$codePrinter->output($parameter['name'] . ' = ' . $parameter['default']['value'] . ';');
break;
case 'double':
$codePrinter->output($parameter['name'] . ' = (int) ' . $parameter['default']['value'] . ';');
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(int)", $parameter);
}
break;
case 'double':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'double') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(double)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$codePrinter->output($parameter['name'] . ' = 0;');
break;
case 'int':
case 'uint':
case 'long':
$codePrinter->output($parameter['name'] . ' = (double) ' . $parameter['default']['value'] . ';');
break;
case 'double':
$codePrinter->output($parameter['name'] . ' = ' . $parameter['default']['value'] . ';');
break;
//.........这里部分代码省略.........
示例7: compile
//.........这里部分代码省略.........
throw new CompilerException("Only dynamic/string variables can be used in new operator. " . $classNameVariable->getName(), $expression);
}
/**
* Use a safe string version of the variable to avoid segfaults
*/
$compilationContext->headersManager->add('kernel/object');
$safeSymbolVariable = $compilationContext->symbolTable->getTempVariable('variable', $compilationContext, $expression);
$safeSymbolVariable->setMustInitNull(true);
$safeSymbolVariable->setIsInitialized(true, $compilationContext, $expression);
$safeSymbolVariable->increaseUses();
$compilationContext->codePrinter->output('zephir_fetch_safe_class(' . $safeSymbolVariable->getName() . ', ' . $classNameVariable->getName() . ');');
$safeSymbol = $compilationContext->backend->getVariableCode($safeSymbolVariable);
$classNameToFetch = 'Z_STRVAL_P(' . $safeSymbol . '), Z_STRLEN_P(' . $safeSymbol . ')';
$zendClassEntry = $compilationContext->cacheManager->getClassEntryCache()->get($classNameToFetch, true, $compilationContext);
$classEntry = $zendClassEntry->getName();
} else {
if (!class_exists($className, false)) {
$compilationContext->logger->warning('Class "' . $className . '" does not exist at compile time', "nonexistent-class", $expression);
$classNameToFetch = 'SL("' . Utils::escapeClassName($className) . '")';
$zendClassEntry = $compilationContext->cacheManager->getClassEntryCache()->get($classNameToFetch, false, $compilationContext);
$classEntry = $zendClassEntry->getName();
} else {
$reflectionClass = new \ReflectionClass($className);
if ($reflectionClass->isInterface()) {
throw new CompilerException('Interfaces cannot be instantiated', $expression);
} else {
if (method_exists($reflectionClass, 'isTrait')) {
if ($reflectionClass->isTrait()) {
throw new CompilerException('Traits cannot be instantiated', $expression);
}
}
}
$classEntry = $compilationContext->classDefinition->getClassEntryByClassName($className, $compilationContext, true);
if (!$classEntry) {
$classNameToFetch = 'SL("' . Utils::escapeClassName($className) . '")';
$zendClassEntry = $compilationContext->cacheManager->getClassEntryCache()->get($classNameToFetch, false, $compilationContext);
$classEntry = $zendClassEntry->getName();
} else {
$symbolVariable->setAssociatedClass($reflectionClass);
}
}
$symbolVariable->setClassTypes($className);
}
$compilationContext->backend->initObject($symbolVariable, $classEntry, $compilationContext);
}
}
/**
* Mark variable initialized
*/
$symbolVariable->setIsInitialized(true, $compilationContext, $expression);
/**
* Don't check the constructor for stdclass instances
*/
if ($isStdClass) {
return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
}
/**
* Call the constructor
* For classes in the same extension we check if the class does implement a constructor
* For external classes we always assume the class does implement a constructor
*/
$callConstructor = false;
if ($compilationContext->compiler->isClass($className)) {
$classDefinition = $compilationContext->compiler->getClassDefinition($className);
if ($classDefinition->getType() != 'class') {
throw new CompilerException("Only classes can be instantiated", $expression);
}
$callConstructor = $classDefinition->hasMethod("__construct");
} else {
if ($compilationContext->compiler->isBundledClass($className)) {
$classDefinition = $compilationContext->compiler->getInternalClassDefinition($className);
$callConstructor = $classDefinition->hasMethod("__construct");
}
}
/* @TODO use the MethodBuilder here */
if (isset($expression['parameters'])) {
$callExpr = new Expression(array('variable' => array('type' => 'variable', 'value' => $symbolVariable->getRealName()), 'name' => '__construct', 'parameters' => $expression['parameters'], 'call-type' => MethodCall::CALL_NORMAL, 'file' => $expression['file'], 'line' => $expression['line'], 'char' => $expression['char'], 'check' => $callConstructor));
} else {
$callExpr = new Expression(array('variable' => array('type' => 'variable', 'value' => $symbolVariable->getRealName()), 'name' => '__construct', 'call-type' => MethodCall::CALL_NORMAL, 'file' => $expression['file'], 'line' => $expression['line'], 'char' => $expression['char'], 'check' => $callConstructor));
}
/**
* If we are certain that there is a constructor we call it, otherwise we checked it at runtime.
*/
if ($callConstructor) {
$methodCall = new MethodCall();
$callExpr->setExpectReturn(false);
$methodCall->compile($callExpr, $compilationContext);
} else {
$compilationContext->headersManager->add('kernel/fcall');
/* @todo, generate the code using builders */
$compilationContext->backend->checkConstructor($symbolVariable, $compilationContext);
$codePrinter->increaseLevel();
$methodCall = new MethodCall();
$callExpr->setExpectReturn(false);
$methodCall->compile($callExpr, $compilationContext);
$codePrinter->decreaseLevel();
$codePrinter->output('}');
}
return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
}
示例8: assignDefaultValue
/**
* Assigns a default value
*
* @param array $parameter
* @param CompilationContext $compilationContext
* @return string
* @throws CompilerException
*/
public function assignDefaultValue(array $parameter, CompilationContext $compilationContext)
{
if (isset($parameter['data-type'])) {
$dataType = $parameter['data-type'];
} else {
$dataType = 'variable';
}
/**
* Class-Hinted parameters only can be null?
*/
if (isset($parameter['cast'])) {
if ($parameter['default']['type'] != 'null') {
throw new CompilerException('Class-Hinted parameters only can have "null" as default parameter', $parameter);
}
}
$code = '';
/**
* @todo Refactoring this place, move to one - static-constant-access
*/
switch ($dataType) {
case 'int':
case 'uint':
case 'long':
case 'ulong':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'int') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(int)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$code .= "\t\t" . $parameter['name'] . ' = 0;' . PHP_EOL;
break;
case 'int':
case 'uint':
case 'long':
$code .= "\t\t" . $parameter['name'] . ' = ' . $parameter['default']['value'] . ';' . PHP_EOL;
break;
case 'double':
$code .= "\t\t" . $parameter['name'] . ' = (int) ' . $parameter['default']['value'] . ';' . PHP_EOL;
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(int)", $parameter);
}
break;
case 'double':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'double') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(double)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$code .= "\t\t" . $parameter['name'] . ' = 0;' . PHP_EOL;
break;
case 'int':
case 'uint':
case 'long':
$code .= "\t\t" . $parameter['name'] . ' = (double) ' . $parameter['default']['value'] . ';' . PHP_EOL;
break;
case 'double':
$code .= "\t\t" . $parameter['name'] . ' = ' . $parameter['default']['value'] . ';' . PHP_EOL;
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(double)", $parameter);
}
break;
case 'bool':
switch ($parameter['default']['type']) {
case 'static-constant-access':
//.........这里部分代码省略.........
示例9: assignStatic
//.........这里部分代码省略.........
$compilationContext->backend->updateStaticProperty($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->updateStaticProperty($classEntry, $property, $tempVariable, $compilationContext);
if ($tempVariable->isTemporal()) {
$tempVariable->setIdle(true);
}
break;
case 'array':
$compilationContext->backend->updateStaticProperty($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);
if ($compilationContext->insideCycle) {
$propertyCache = $compilationContext->symbolTable->getTempVariableForWrite('zend_property_info', $compilationContext);
$propertyCache->setMustInitNull(true);
$propertyCache->setReusable(false);
$codePrinter->output('zephir_update_static_property_ce_cache(' . $classEntry . ', SL("' . $property . '"), &' . $tempVariable->getName() . ', &' . $propertyCache->getName() . ' TSRMLS_CC);');
} else {
$compilationContext->backend->updateStaticProperty($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);
if ($compilationContext->insideCycle) {
$propertyCache = $compilationContext->symbolTable->getTempVariableForWrite('zend_property_info', $compilationContext);
$propertyCache->setMustInitNull(true);
$propertyCache->setReusable(false);
$codePrinter->output('zephir_update_static_property_ce_cache(' . $classEntry . ', SL("' . $property . '"), &' . $tempVariable->getName() . ', &' . $propertyCache->getName() . ' TSRMLS_CC);');
} else {
$compilationContext->backend->updateStaticProperty($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->updateStaticProperty($classEntry, $property, $tempVariable, $compilationContext);
if ($tempVariable->isTemporal()) {
$tempVariable->setIdle(true);
}
break;
case 'string':
switch ($statement['operator']) {
case 'concat-assign':
$tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable('variable', $compilationContext, true);
$expression = new Expression(array('type' => 'static-property-access', 'left' => array('value' => $statement['variable']), 'right' => array('value' => $statement['property'])));
$expression->setExpectReturn(true, $tempVariable);
$expression->compile($compilationContext);
$variableVariableCode = $compilationContext->backend->getVariableCode($variableVariable);
$tempVariableCode = $compilationContext->backend->getVariableCode($tempVariable);
$compilationContext->codePrinter->output('zephir_concat_function(' . $variableVariableCode . ', ' . $tempVariableCode . ', ' . $variableVariableCode . ');');
//continue
//continue
case 'assign':
$compilationContext->backend->updateStaticProperty($classEntry, $property, $variableVariable, $compilationContext);
if ($variableVariable->isTemporal()) {
$variableVariable->setIdle(true);
}
break;
default:
throw new CompilerException("Operator '" . $statement['operator'] . "' is not supported for variable type: string", $statement);
}
break;
case 'variable':
case 'array':
$compilationContext->backend->updateStaticProperty($classEntry, $property, $variableVariable, $compilationContext);
if ($variableVariable->isTemporal()) {
$variableVariable->setIdle(true);
}
break;
default:
throw new CompilerException("Unknown type " . $variableVariable->getType(), $statement);
}
break;
default:
throw new CompilerException("Unknown type " . $resolvedExpr->getType(), $statement);
}
}
示例10: compile
/**
* @param CompilationContext $compilationContext
* @throws CompilerException
*/
public function compile(CompilationContext $compilationContext)
{
$statement = $this->_statement;
$codePrinter = $compilationContext->codePrinter;
if (isset($statement['expr'])) {
$currentMethod = $compilationContext->currentMethod;
if ($currentMethod->isConstructor()) {
throw new CompilerException("Constructors cannot return values", $statement['expr']);
}
if ($currentMethod->isVoid()) {
throw new CompilerException("Method is marked as 'void' and it must not return any value", $statement['expr']);
}
/**
* Use return member for properties on this
*/
if ($statement['expr']['type'] == 'property-access') {
if ($statement['expr']['left']['type'] == 'variable') {
if ($statement['expr']['left']['value'] == 'this') {
if ($statement['expr']['right']['type'] == 'variable') {
/**
* If the property is accessed on 'this', we check if the property does exist
*/
$property = $statement['expr']['right']['value'];
$classDefinition = $compilationContext->classDefinition;
if (!$classDefinition->hasProperty($property)) {
throw new CompilerException("Class '" . $classDefinition->getCompleteName() . "' does not have a property called: '" . $property . "'", $statement['expr']['right']);
}
$compilationContext->headersManager->add('kernel/object');
$codePrinter->output('RETURN_MM_MEMBER(this_ptr, "' . $property . '");');
return;
}
}
}
}
/**
* Fetches return_value and tries to return the value directly there
*/
$variable = $compilationContext->symbolTable->getVariable('return_value');
$expr = new Expression($statement['expr']);
$expr->setExpectReturn(true, $variable);
$expr->setReadOnly(true);
$resolvedExpr = $expr->compile($compilationContext);
/**
* Here we check if the variable returns a compatible type according to its type hints
*/
if ($currentMethod->hasReturnTypes()) {
switch ($resolvedExpr->getType()) {
case 'null':
if (!$currentMethod->areReturnTypesNullCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'int':
case 'uint':
case 'long':
case 'char':
case 'uchar':
if (!$currentMethod->areReturnTypesIntCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'bool':
if (!$currentMethod->areReturnTypesBoolCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'double':
if (!$currentMethod->areReturnTypesDoubleCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'string':
if (!$currentMethod->areReturnTypesStringCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'variable':
$symbolVariable = $compilationContext->symbolTable->getVariableForRead($resolvedExpr->getCode(), $compilationContext, $statement['expr']);
switch ($symbolVariable->getType()) {
case 'int':
case 'uint':
case 'long':
case 'char':
case 'uchar':
if (!$currentMethod->areReturnTypesIntCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'double':
if (!$currentMethod->areReturnTypesDoubleCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
}
break;
case 'string':
if (!$currentMethod->areReturnTypesStringCompatible()) {
throw new CompilerException("Returning type: " . $resolvedExpr->getType() . " but this type is not compatible with return-type hints declared in the method", $statement['expr']);
//.........这里部分代码省略.........
示例11: compile
/**
* @param CompilationContext $compilationContext
* @throws CompilerException
*/
public function compile(CompilationContext $compilationContext)
{
$readDetector = new ReadDetector();
$statement = $this->_statement;
foreach ($statement['assignments'] as $assignment) {
$variable = $assignment['variable'];
/**
* Get the symbol from the symbol table if necessary
*/
switch ($assignment['assign-type']) {
case 'static-property':
case 'static-property-append':
case 'static-property-array-index':
case 'static-property-array-index-append':
case 'dynamic-variable-string':
$symbolVariable = null;
break;
case 'array-index':
case 'variable-append':
case 'object-property':
case 'array-index-append':
case 'string-dynamic-object-property':
case 'variable-dynamic-object-property':
$symbolVariable = $compilationContext->symbolTable->getVariableForUpdate($variable, $compilationContext, $assignment);
break;
default:
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($variable, $compilationContext, $assignment);
break;
}
/**
* Incr/Decr assignments don't require an expression
*/
if (isset($assignment['expr'])) {
$expr = new Expression($assignment['expr']);
switch ($assignment['assign-type']) {
case 'variable':
if (!$readDetector->detect($variable, $assignment['expr'])) {
if (isset($assignment['operator'])) {
if ($assignment['operator'] == 'assign') {
$expr->setExpectReturn(true, $symbolVariable);
}
} else {
$expr->setExpectReturn(true, $symbolVariable);
}
} else {
if (isset($assignment['operator'])) {
if ($assignment['operator'] == 'assign') {
$expr->setExpectReturn(true);
}
} else {
$expr->setExpectReturn(true);
}
}
break;
}
switch ($assignment['expr']['type']) {
case 'property-access':
case 'array-access':
case 'type-hint':
$expr->setReadOnly(true);
break;
}
$resolvedExpr = $expr->compile($compilationContext);
/**
* Bad implemented operators could return values different than objects
*/
if (!is_object($resolvedExpr)) {
throw new CompilerException("Resolved expression is not valid", $assignment['expr']);
}
}
/**
* There are four types of assignments
*/
switch ($assignment['assign-type']) {
case 'variable':
$let = new LetVariable();
$let->assign($variable, $symbolVariable, $resolvedExpr, $readDetector, $compilationContext, $assignment);
break;
case 'variable-append':
$let = new LetVariableAppend();
$let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
break;
case 'object-property':
$let = new LetObjectProperty();
$let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
break;
case 'variable-dynamic-object-property':
$let = new LetObjectDynamicProperty();
$let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
break;
case 'string-dynamic-object-property':
$let = new LetObjectDynamicStringProperty();
$let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
break;
case 'static-property':
$let = new LetStaticProperty();
//.........这里部分代码省略.........
示例12: compile
//.........这里部分代码省略.........
break;
case 'bool':
switch ($defaultType) {
case 'bool':
if ($variable['expr']['value'] == 'true') {
$defaultValue = 1;
} else {
$defaultValue = 0;
}
break;
case 'null':
$defaultValue = 0;
break;
default:
self::invalidDefaultTypeException($variable['expr']['type'], $statement['data-type'], $variable);
}
break;
case 'char':
case 'uchar':
switch ($defaultType) {
case 'char':
case 'uchar':
$defaultValue = '\'' . $defaultValue . '\'';
break;
case 'int':
break;
case 'null':
$defaultValue = 0;
break;
default:
self::invalidDefaultTypeException($variable['expr']['type'], $statement['data-type'], $variable);
}
break;
case 'string':
$defaultValue = $variable['expr'];
switch ($defaultType) {
case 'string':
case 'null':
break;
default:
self::invalidDefaultTypeException($variable['expr']['type'], $statement['data-type'], $variable);
}
break;
case 'array':
$defaultValue = $variable['expr'];
switch ($defaultType) {
case 'null':
case 'array':
case 'empty-array':
break;
default:
self::invalidDefaultTypeException($variable['expr']['type'], $statement['data-type'], $variable);
}
break;
case 'variable':
$defaultValue = $variable['expr'];
switch ($defaultType) {
case 'int':
case 'uint':
case 'long':
case 'char':
case 'uchar':
$symbolVariable->setDynamicTypes('long');
break;
case 'double':
$symbolVariable->setDynamicTypes('double');
break;
case 'string':
case 'ulong':
$symbolVariable->setDynamicTypes('string');
break;
case 'array':
$expression = new Expression($variable['expr']);
$expression->setExpectReturn(true, $symbolVariable);
$expression->compile($compilationContext);
// no break
// no break
case 'array':
case 'empty-array':
$symbolVariable->setDynamicTypes('array');
break;
case 'null':
$symbolVariable->setDynamicTypes('null');
$symbolVariable->setMustInitNull(true);
$symbolVariable->setLocalOnly(false);
break;
default:
self::invalidDefaultTypeException($defaultType, $statement['data-type'], $variable);
}
break;
default:
throw new CompilerException('Invalid variable type: ' . $currentType, $variable);
}
$symbolVariable->setDefaultInitValue($defaultValue);
$symbolVariable->setIsInitialized(true, $compilationContext);
$symbolVariable->increaseMutates();
$symbolVariable->setPossibleValue(new LiteralCompiledExpression($defaultType, $defaultValue, $variable['expr']), $compilationContext);
}
}
}