- Move compiler diagnostic methods to CompilerDiagnosticTrait - Extract unary expression parsing logic to UnaryExpressionTrait - Remove unused TestError exception import - Add proper trait usage in CompilerBase class -pull/17/head
parent
41aaff4094
commit
688993e587
3 changed files with 151 additions and 117 deletions
@ -0,0 +1,65 @@ |
||||
<?php |
||||
/** |
||||
* This file is part of TypePHP. |
||||
* |
||||
* @link https://www.swoole.com/ |
||||
* @contact service@swoole.com |
||||
*/ |
||||
|
||||
namespace TypePhp\Diagnostics; |
||||
|
||||
use PhpParser\Node; |
||||
use PhpParser\Node\Expr\Variable; |
||||
use PhpParser\NodeAbstract; |
||||
use TypePhp\Exception\TestError; |
||||
|
||||
trait CompilerDiagnosticTrait |
||||
{ |
||||
/** |
||||
* Report a compiler fatal error. |
||||
*/ |
||||
public function error(string $msg): never |
||||
{ |
||||
if ($this->forTest) { |
||||
throw new TestError($msg); |
||||
} |
||||
|
||||
$this->climate->red("Fatal error: {$msg}"); |
||||
if ($this->printBacktraceOnError) { |
||||
debug_print_backtrace(); |
||||
} |
||||
exit(255); |
||||
} |
||||
|
||||
public function fatalError(NodeAbstract $node, string $msg): never |
||||
{ |
||||
$this->error("{$msg} in {$this->file}:{$node->getStartLine()}"); |
||||
} |
||||
|
||||
protected function warning(Node $node, string $msg): void |
||||
{ |
||||
$this->climate->magenta("{$msg} in {$this->file}:{$node->getStartLine()}"); |
||||
} |
||||
|
||||
protected function errorUndefinedVariable(Variable $node): never |
||||
{ |
||||
$this->fatalError($node, "The variable `\${$node->name}` is undefined"); |
||||
} |
||||
|
||||
protected function warningUndefinedBehavior(NodeAbstract $expr): void |
||||
{ |
||||
$this->warning($expr, 'Use this expression carefully, which may be inconsistent with the dynamic execution behavior'); |
||||
} |
||||
|
||||
protected function dump(NodeAbstract $node): void |
||||
{ |
||||
if ($this->debugLine == $node->getStartLine()) { |
||||
var_dump($node); |
||||
} |
||||
} |
||||
|
||||
protected function foundStrayCode(Node $node): never |
||||
{ |
||||
$this->fatalError($node, 'All execution code must be within a function, found stray code'); |
||||
} |
||||
} |
||||
@ -0,0 +1,82 @@ |
||||
<?php |
||||
/** |
||||
* This file is part of TypePHP. |
||||
* |
||||
* @link https://www.swoole.com/ |
||||
* @contact service@swoole.com |
||||
*/ |
||||
|
||||
namespace TypePhp\Parser; |
||||
|
||||
use PhpParser\Node\Expr; |
||||
|
||||
trait UnaryExpressionTrait |
||||
{ |
||||
protected function parseBitwiseNot(Expr\BitwiseNot $expr): string |
||||
{ |
||||
$type = $this->detectTypeOfExpr($expr->expr); |
||||
$this->assertExprCanBeUsedAsValue($expr->expr, 'bitwise operand'); |
||||
if ($type === self::TYPE_BIGINT) { |
||||
return 'php::BigInt::bitNot(' . $this->parseExpr($expr->expr) . ')'; |
||||
} |
||||
$var = $this->parseIdentifier($expr->expr); |
||||
return '~' . $this->convertIntExpr($var); |
||||
} |
||||
|
||||
protected function parseBooleanNot(Expr\BooleanNot $expr): string |
||||
{ |
||||
$this->assertExprCanBeUsedAsCondition($expr->expr, 'boolean operand'); |
||||
return '!(' . $this->parseExprAsValue($expr->expr) . ')'; |
||||
} |
||||
|
||||
protected function parseCastInt(Expr\Cast\Int_ $node): string |
||||
{ |
||||
$this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); |
||||
return $this->convertIntExpr($this->parseExprAsValue($node->expr)); |
||||
} |
||||
|
||||
protected function parseCastString(Expr\Cast\String_ $node): string |
||||
{ |
||||
$this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); |
||||
return $this->convertExprToStringByType( |
||||
$this->parseExprAsValue($node->expr), |
||||
$this->detectTypeOfExpr($node->expr) |
||||
); |
||||
} |
||||
|
||||
protected function parseCastBool(Expr\Cast\Bool_ $node): string |
||||
{ |
||||
$this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); |
||||
return $this->convertBoolExpr($this->parseExprAsValue($node->expr)); |
||||
} |
||||
|
||||
protected function parseCastObject(Expr\Cast\Object_ $node): string |
||||
{ |
||||
$this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); |
||||
return $this->convertObjectExpr($this->parseExprAsValue($node->expr)); |
||||
} |
||||
|
||||
protected function parseUnaryMinus(Expr\UnaryMinus $expr): string |
||||
{ |
||||
$type = $this->detectTypeOfExpr($expr->expr); |
||||
$this->assertExprCanBeUsedAsValue($expr->expr, 'unary operand'); |
||||
if ($type === self::TYPE_BIGFLOAT) { |
||||
return 'php::BigFloat::neg(' . $this->parseExprAsValue($expr->expr) . ')'; |
||||
} |
||||
if ($type === self::TYPE_BIGINT) { |
||||
return 'php::BigInt::neg(' . $this->parseExprAsValue($expr->expr) . ')'; |
||||
} |
||||
if ($type === self::TYPE_DECIMAL) { |
||||
return 'php::Decimal::neg(' . $this->parseExprAsValue($expr->expr) . ')'; |
||||
} |
||||
$code = $this->parseExprAsValue($expr->expr); |
||||
|
||||
return '-' . $code; |
||||
} |
||||
|
||||
protected function parseUnaryPlus(Expr\UnaryPlus $expr): string |
||||
{ |
||||
$this->assertExprCanBeUsedAsValue($expr->expr, 'unary operand'); |
||||
return $this->parseExprAsValue($expr->expr); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue