- 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