|
|
|
|
@ -1,4 +1,5 @@ |
|
|
|
|
<?php |
|
|
|
|
|
|
|
|
|
declare(strict_types=1); |
|
|
|
|
|
|
|
|
|
namespace PhpAot\Php; |
|
|
|
|
@ -10,6 +11,8 @@ use PhpParser\Node\Expr\Variable; |
|
|
|
|
use PhpParser\Node\Identifier; |
|
|
|
|
use PhpParser\Error; |
|
|
|
|
use PhpParser\Node\NullableType; |
|
|
|
|
use PhpParser\Node\Scalar\MagicConst; |
|
|
|
|
use PhpParser\Node\Stmt\Foreach_; |
|
|
|
|
use PhpParser\NodeFinder; |
|
|
|
|
use PhpParser\NodeTraverser; |
|
|
|
|
use PhpParser\Parser; |
|
|
|
|
@ -20,22 +23,22 @@ use stdClass; |
|
|
|
|
|
|
|
|
|
class Translator extends \PhpAot\Core\Translator |
|
|
|
|
{ |
|
|
|
|
const string TYPE_VAR = 'php::Var'; |
|
|
|
|
const string TYPE_BOOL = 'php::Bool'; |
|
|
|
|
const string TYPE_INT = 'php::Int'; |
|
|
|
|
const string TYPE_FLOAT = 'php::Float'; |
|
|
|
|
const string TYPE_OBJECT = 'php::Object'; |
|
|
|
|
const string TYPE_ARRAY = 'php::Array'; |
|
|
|
|
const string TYPE_STR = 'php::Str'; |
|
|
|
|
const string TYPE_REF = 'php::Var'; |
|
|
|
|
|
|
|
|
|
const string VALUE_NAN = 'std::numeric_limits<double>::quiet_NaN()'; |
|
|
|
|
const string VALUE_INF = 'std::numeric_limits<double>::infinity()'; |
|
|
|
|
const string LITERAL_STRINGS = '_literal_strings'; |
|
|
|
|
const string EXPR_VARIABLE = 'Expr_Variable'; |
|
|
|
|
const string EXPR_NEW = 'Expr_New'; |
|
|
|
|
const string EXPR_ARRAY_DIM_FETCH = 'Expr_ArrayDimFetch'; |
|
|
|
|
const string NAMESPACE_SEPARATOR = '__'; |
|
|
|
|
public const string TYPE_VAR = 'php::Var'; |
|
|
|
|
public const string TYPE_BOOL = 'php::Bool'; |
|
|
|
|
public const string TYPE_INT = 'php::Int'; |
|
|
|
|
public const string TYPE_FLOAT = 'php::Float'; |
|
|
|
|
public const string TYPE_OBJECT = 'php::Object'; |
|
|
|
|
public const string TYPE_ARRAY = 'php::Array'; |
|
|
|
|
public const string TYPE_STR = 'php::Str'; |
|
|
|
|
public const string TYPE_REF = 'php::Var'; |
|
|
|
|
|
|
|
|
|
public const string VALUE_NAN = 'std::numeric_limits<double>::quiet_NaN()'; |
|
|
|
|
public const string VALUE_INF = 'std::numeric_limits<double>::infinity()'; |
|
|
|
|
public const string LITERAL_STRINGS = '_literal_strings'; |
|
|
|
|
public const string EXPR_VARIABLE = 'Expr_Variable'; |
|
|
|
|
public const string EXPR_NEW = 'Expr_New'; |
|
|
|
|
public const string EXPR_ARRAY_DIM_FETCH = 'Expr_ArrayDimFetch'; |
|
|
|
|
public const string NAMESPACE_SEPARATOR = '__'; |
|
|
|
|
|
|
|
|
|
private string $phpxDir = '~/workspace/projects/phpx'; |
|
|
|
|
protected string $lang = 'PHP'; |
|
|
|
|
@ -137,7 +140,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
private array $objectWrappers = []; |
|
|
|
|
private bool $strictTypes = false; |
|
|
|
|
|
|
|
|
|
const string PREFIX = 'php_'; |
|
|
|
|
public const string PREFIX = 'php_'; |
|
|
|
|
private string $rootPath; |
|
|
|
|
private string $buildDir; |
|
|
|
|
private int $debugLine = 0; |
|
|
|
|
@ -155,7 +158,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$this->parser = (new ParserFactory())->createForNewestSupportedVersion(); |
|
|
|
|
// $this->prettyPrinter = new PrettyPrinter\Standard; |
|
|
|
|
$this->setBuildDir($rootPath . '/build'); |
|
|
|
|
$climate = new CLImate; |
|
|
|
|
$climate = new CLImate(); |
|
|
|
|
$this->climate = $climate; |
|
|
|
|
$climate->arguments->add([ |
|
|
|
|
'optimize' => [ |
|
|
|
|
@ -203,7 +206,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$this->internalFunctions = array_flip(get_defined_functions()['internal']); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function showUsage(): void |
|
|
|
|
public function showUsage(): void |
|
|
|
|
{ |
|
|
|
|
$climate = $this->climate; |
|
|
|
|
$climate->bold()->green('PHP AOT Compiler v1.0.0'); |
|
|
|
|
@ -234,7 +237,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$climate->br(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function preprocessArgvAdvanced(): void |
|
|
|
|
public function preprocessArgvAdvanced(): void |
|
|
|
|
{ |
|
|
|
|
global $argv; |
|
|
|
|
$processed = [$argv[0]]; |
|
|
|
|
@ -289,7 +292,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$this->climate->info('convert: ' . $this->file); |
|
|
|
|
|
|
|
|
|
$ast = $this->parser->parse($phpCode); |
|
|
|
|
$traverser = new NodeTraverser; |
|
|
|
|
$traverser = new NodeTraverser(); |
|
|
|
|
$traverser->addVisitor(new Visitor()); |
|
|
|
|
|
|
|
|
|
$stmts = $traverser->traverse($ast); |
|
|
|
|
@ -451,7 +454,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
if (isset($this->redoAfterDeclare[$name])) { |
|
|
|
|
unset($this->redoAfterDeclare[$name]); |
|
|
|
|
$this->climate->cyan('Received redo request, retrying...'); |
|
|
|
|
throw new RedoException; |
|
|
|
|
throw new RedoException(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -510,6 +513,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$index = $this->literalStrings[$expr->value] ?? $this->addLiteralString($expr->value); |
|
|
|
|
return self::LITERAL_STRINGS . '[' . $index . ']'; |
|
|
|
|
} |
|
|
|
|
// no break |
|
|
|
|
default: |
|
|
|
|
abort($expr); |
|
|
|
|
} |
|
|
|
|
@ -1022,7 +1026,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$this->functionDef->returnType = $type; |
|
|
|
|
// 返回值变更,需要重新解析 |
|
|
|
|
$this->climate->cyan('Return type changed, retrying...'); |
|
|
|
|
throw new RedoException; |
|
|
|
|
throw new RedoException(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function detectVarType($var): string |
|
|
|
|
@ -1692,7 +1696,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
return $code; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function isClosedCall($expr, $call): bool |
|
|
|
|
public function isClosedCall($expr, $call): bool |
|
|
|
|
{ |
|
|
|
|
if ($call === '') { |
|
|
|
|
if (!str_starts_with($expr, '(')) { |
|
|
|
|
@ -2118,7 +2122,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
return $var . ' ^= ' . $this->parseIdentifier($node->expr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function parseMagicConst(mixed $expr): string |
|
|
|
|
private function parseMagicConst(MagicConst $expr): string |
|
|
|
|
{ |
|
|
|
|
switch ($expr->getType()) { |
|
|
|
|
case 'Scalar_MagicConst_Dir': |
|
|
|
|
@ -2126,7 +2130,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
case 'Scalar_MagicConst_File': |
|
|
|
|
return '"' . $this->escapeString($this->file) . '"'; |
|
|
|
|
case 'Scalar_MagicConst_Line': |
|
|
|
|
return $expr->getStartLine(); |
|
|
|
|
return (string)$expr->getStartLine(); |
|
|
|
|
case 'Scalar_MagicConst_Function': |
|
|
|
|
return '"' . $this->escapeString($this->functionDef->name) . '"'; |
|
|
|
|
default: |
|
|
|
|
@ -2134,7 +2138,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private function parseForeach(Node $node): string |
|
|
|
|
private function parseForeach(Foreach_ $node): string |
|
|
|
|
{ |
|
|
|
|
if ($node->byRef) { |
|
|
|
|
$this->fatalError($node, 'Cannot use & with foreach'); |
|
|
|
|
@ -2740,7 +2744,7 @@ class Translator extends \PhpAot\Core\Translator |
|
|
|
|
$this->climate->info('prepare: ' . $this->file); |
|
|
|
|
$ast = $this->parser->parse($phpCode); |
|
|
|
|
|
|
|
|
|
$traverser = new NodeTraverser; |
|
|
|
|
$traverser = new NodeTraverser(); |
|
|
|
|
$traverser->addVisitor(new Visitor()); |
|
|
|
|
$stmts = $traverser->traverse($ast); |
|
|
|
|
|
|
|
|
|
|