From 8c20fd18c8313fdcd317853a7dfb5a666ee068d8 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 29 Jan 2026 18:25:43 +0800 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=BB=93=E6=9E=84=E5=92=8C=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整 import 语句顺序,将 Node 相关引入规范化 - 规范化字符串拼接操作,统一使用点号连接 - 统一比较运算符写法,调整变量与常量的比较顺序 - 移除多余空行和分号,精简代码结构 - 标准化缩进和代码格式,提升可读性 - 优化循环和条件判断逻辑,使用前置递增递减 - 修复类定义和方法定义的格式一致性 - 更新依赖管理方式,优化编译器配置加载 --- src/Php/AstNodeType.php | 5 +- src/Php/ClassDef.php | 2 +- src/Php/ClassLikeDef.php | 10 +- src/Php/CompilerBase.php | 902 ++++++++++++++++++-------------- src/Php/ConstantDef.php | 2 +- src/Php/Constants.php | 4 +- src/Php/Encryptor.php | 82 +-- src/Php/Extractor.php | 121 ++--- src/Php/FileScanner.php | 8 +- src/Php/FileSorter.php | 10 +- src/Php/FuncCallOptimizer.php | 16 +- src/Php/FunctionDef.php | 1 - src/Php/InterfaceDef.php | 2 +- src/Php/MagicMethodDetector.php | 16 +- src/Php/Preprocessor.php | 24 +- src/Php/PropertyDef.php | 4 +- src/Php/Reflection.php | 15 +- src/Php/SyntaxError.php | 3 +- src/Php/Translator.php | 267 +++++----- src/template/extension.cc.php | 17 + 20 files changed, 829 insertions(+), 682 deletions(-) diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index fee75bee..67a6d865 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -2,9 +2,9 @@ namespace PhpAot\Php; +use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\NodeAbstract; -use PhpParser\Node; trait AstNodeType { @@ -12,6 +12,7 @@ trait AstNodeType { return $expr instanceof Expr\ArrayDimFetch; } + protected function isVarExpr(NodeAbstract $expr): bool { return $expr instanceof Expr\Variable; @@ -51,4 +52,4 @@ trait AstNodeType { return $expr instanceof Expr\FuncCall; } -} \ No newline at end of file +} diff --git a/src/Php/ClassDef.php b/src/Php/ClassDef.php index b4f63cd4..49f1ae3a 100644 --- a/src/Php/ClassDef.php +++ b/src/Php/ClassDef.php @@ -41,4 +41,4 @@ class ClassDef extends ClassLikeDef { return $this->properties[$property]; } -} \ No newline at end of file +} diff --git a/src/Php/ClassLikeDef.php b/src/Php/ClassLikeDef.php index 40c40011..b66b2777 100644 --- a/src/Php/ClassLikeDef.php +++ b/src/Php/ClassLikeDef.php @@ -8,7 +8,6 @@ class ClassLikeDef public string $namespace; public string $extends = ''; - public function __construct(string $name, string $namespace = '') { $this->name = $name; @@ -17,12 +16,13 @@ class ClassLikeDef public function getNamespacedName(bool $symbolic = true): string { - if ($this->namespace === '') { + if ('' === $this->namespace) { return $this->name; } if ($symbolic) { - return str_replace('\\', '_', $this->namespace . '_' . $this->name); + return str_replace('\\', '_', $this->namespace.'_'.$this->name); } - return $this->namespace . '\\\\' . $this->name; + + return $this->namespace.'\\\\'.$this->name; } -} \ No newline at end of file +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index c361135a..a3e24ace 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1,29 +1,20 @@ ::quiet_NaN()'; public const string VALUE_INF = 'std::numeric_limits::infinity()'; public const string LITERAL_STRINGS = '_literal_strings'; + public const string CLASS_ENTRY_MAP = 'class_entry_map'; public const string EXPR_VARIABLE = 'Expr_Variable'; public const string EXPR_NEW = 'Expr_New'; public const string EXPR_ARRAY_DIM_FETCH = 'Expr_ArrayDimFetch'; @@ -54,6 +46,11 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $literalStrings = []; protected int $literalStringIndex = 0; protected int $tmpVarIndex = 0; + protected int $classIndex = 0; + /** + * @var array + */ + protected array $classMap = []; protected array $zendTypeMap = [ 'int' => self::TYPE_INT, 'float' => self::TYPE_FLOAT, @@ -90,17 +87,15 @@ class CompilerBase extends \PhpAot\Core\Translator protected string $file; protected string $dir; /** - * 原始值,可能包含 `\\` 多层空间 - * @var string + * 原始值,可能包含 `\\` 多层空间. */ protected string $namespace = ''; - protected string $method = ''; + protected string $method = ''; protected string $function = ''; protected array $useNamespaces = []; protected array $useFunctions = []; /** - * 原始类名,不包含命名空间 - * @var string + * 原始类名,不包含命名空间. */ protected string $class = ''; protected string $interface = ''; @@ -162,8 +157,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $afterStmtLines = []; protected bool $inLoop = false; /** - * 赋值表达式的左值,写操作,右值为读操作 - * @var bool + * 赋值表达式的左值,写操作,右值为读操作. */ protected bool $inAssignExpr = false; protected bool $stubFile = false; @@ -175,7 +169,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->rootPath = $rootPath; $this->parser = (new ParserFactory())->createForNewestSupportedVersion(); // $this->prettyPrinter = new PrettyPrinter\Standard; - $this->setBuildDir($rootPath . '/build'); + $this->setBuildDir($rootPath.'/build'); $climate = new CLImate(); $this->climate = $climate; // $this->noLiteralStrings = $climate->arguments->get('no-literal-strings'); @@ -191,13 +185,14 @@ class CompilerBase extends \PhpAot\Core\Translator $len = min(strlen($short), strlen($long)); $prefixLen = 0; - for ($i = 0; $i < $len; $i++) { + for ($i = 0; $i < $len; ++$i) { if ($short[$i] === $long[$i]) { - $prefixLen++; + ++$prefixLen; } else { break; } } + return substr($long, $prefixLen); } @@ -225,6 +220,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->hasLocalVar($name)) { return $this->globalVars[$name]; } + return self::TYPE_VAR; } @@ -283,7 +279,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function getPropertyOffset(string $property, string $class, string $namespace = ''): string { - return $this->getNativeName('property_offset_' . $property, $namespace, $class); + return $this->getNativeName('property_offset_'.$property, $namespace, $class); } protected function getNativeName(string $fn, string $ns = '', string $class = ''): string @@ -295,23 +291,37 @@ class CompilerBase extends \PhpAot\Core\Translator if ($class) { $names[] = $this->escapeClass($class); } + return implode(self::NAMESPACE_SEPARATOR, array_reverse($names)); } + protected function getClassEntryPtr(string $className): string + { + if (isset($this->classMap[$className])) { + $id = $this->classMap[$className]; + } else { + $id = $this->classIndex++; + $this->classMap[$className] = $id; + } + + return 'php_get_class_entry('.$id.', "'.$this->escapeString($className).'")'; + } + protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef { // .stub 存根定义 C++ Native 函数,必须设置返回值类型 if (!$v->returnType && $this->stubFile) { - throw new Exception('No return type for ' . $v->name); + throw new \Exception('No return type for '.$v->name); } $returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID; $functionDef = new FunctionDef($this->parseIdentifier($v->name), $returnType); $this->functionDef = $functionDef; $this->parseParams($v->params, $functionDef); + return $functionDef; } - protected function parseFunction(Node\FunctionLike $v): string + protected function parseFunction(FunctionLike $v): string { $this->resetFunction(); $this->function = $this->parseIdentifier($v->name); @@ -343,32 +353,32 @@ class CompilerBase extends \PhpAot\Core\Translator } if ($v->stmts) { - $this->indentLevel++; + ++$this->indentLevel; $stmts = $this->parseStmts($v->stmts); - $this->indentLevel--; + --$this->indentLevel; } else { $stmts = ''; } - $functionDeclCode = $this->getReturnType() . ' ' . self::PREFIX . $name . '('; + $functionDeclCode = $this->getReturnType().' '.self::PREFIX.$name.'('; if ($this->class) { - $functionDeclCode .= self::TYPE_OBJECT . ' &this_'; + $functionDeclCode .= self::TYPE_OBJECT.' &this_'; if ($this->functionDef->params) { $functionDeclCode .= ', '; } } - $functionDeclCode .= $this->functionDef->params . ')'; + $functionDeclCode .= $this->functionDef->params.')'; - $code = $functionDeclCode . ' {' . PHP_EOL; - $this->indentLevel++; + $code = $functionDeclCode.' {'.PHP_EOL; + ++$this->indentLevel; foreach ($this->localVars as $name => $type) { if (isset($this->arguments[$name])) { continue; } - $code .= $this->getIndent() . $type . ' ' . $name . ';' . PHP_EOL; + $code .= $this->getIndent().$type.' '.$name.';'.PHP_EOL; } $code .= "\n"; - $this->indentLevel--; + --$this->indentLevel; $code .= $stmts; $code .= "}\n"; @@ -380,7 +390,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function writeLog($msg) { if ($this->verbose) { - echo $msg . PHP_EOL; + echo $msg.PHP_EOL; } } @@ -389,15 +399,16 @@ class CompilerBase extends \PhpAot\Core\Translator $type = $expr->getType(); switch ($type) { case 'Scalar_Int': - return $expr->value . 'L'; + return $expr->value.'L'; case 'Scalar_Float': return $this->parseScalarFloat($expr); case 'Scalar_String': if ($this->noLiteralStrings) { - return '"' . $this->escapeString($expr->value) . '"'; + return '"'.$this->escapeString($expr->value).'"'; } else { $index = $this->literalStrings[$expr->value] ?? $this->addLiteralString($expr->value); - return self::LITERAL_STRINGS . '[' . $index . ']'; + + return self::LITERAL_STRINGS.'['.$index.']'; } // no break default: @@ -413,6 +424,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (is_object($expr->name) and $this->isVarExpr($expr->name)) { $this->fatalError($expr, 'The `$$` syntax is not supported'); } + return $this->escapeVarName($expr->name); case 'Name': case 'VarLikeIdentifier': @@ -429,6 +441,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->isVarExpr($expr->var)) { $this->fatalError($expr, 'When an assignment expression serves as an rvalue, it must be an assignment of a variable'); } + return $this->parseExpr($expr); default: return $this->parseExpr($expr); @@ -442,11 +455,11 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($params as $param) { // .stub 存根定义 C++ Native 函数,必须设置函数的参数类型 if ($this->stubFile and !$param->type) { - throw new RuntimeException('No type for ' . $this->parseIdentifier($param->var)); + throw new \RuntimeException('No type for '.$this->parseIdentifier($param->var)); } $name = $this->parseIdentifier($param->var); $type = $this->parseParameterType($param, $name); - $list[] = $type . ' ' . $name; + $list[] = $type.' '.$name; $argInfo = new ArgInfo(); $argInfo->name = $name; $argInfo->type = $type; @@ -461,23 +474,24 @@ class CompilerBase extends \PhpAot\Core\Translator protected function getComment(Node\Stmt $v, string $class): string { - if ($class == 'Stmt_Expression') { - $class = 'Stmt_Expression(' . $v->expr->getType() . ')'; + if ('Stmt_Expression' == $class) { + $class = 'Stmt_Expression('.$v->expr->getType().')'; } - return $this->getIndent() . '// ' . $class . ' [' . $v->getStartLine() . ':' . $v->getEndLine() . ']'; + + return $this->getIndent().'// '.$class.' ['.$v->getStartLine().':'.$v->getEndLine().']'; } /** * 在 for/foreach 等包含子语句的语句,之前检查当前待添加的代码是否为空, - * 如果不为空,需要将语句追加到 {} 作用域符号之前 - * @return string + * 如果不为空,需要将语句追加到 {} 作用域符号之前. */ protected function parseBeforeStmtLines(): string { if ($this->beforeStmtLines) { $code = implode(PHP_EOL, $this->beforeStmtLines); $this->beforeStmtLines = []; - return $code . PHP_EOL; + + return $code.PHP_EOL; } else { return ''; } @@ -492,18 +506,18 @@ class CompilerBase extends \PhpAot\Core\Translator $this->beforeStmtLines = []; $this->afterStmtLines = []; $result = ''; - $this->writeLog('Line ' . $this->getLine($v) . ': ' . $class); + $this->writeLog('Line '.$this->getLine($v).': '.$class); $lines[] = $this->getComment($v, $class); switch ($class) { case 'Stmt_Expression': - $result = $this->parseExpr($v->expr) . ';'; + $result = $this->parseExpr($v->expr).';'; break; case 'Stmt_Echo': $result = $this->parseEcho($v); break; case 'Stmt_Return': - $result = $this->parseReturn($v) . ';'; + $result = $this->parseReturn($v).';'; break; case 'Stmt_For': $this->inLoop = true; @@ -578,15 +592,16 @@ class CompilerBase extends \PhpAot\Core\Translator $code = ''; foreach ($lines as $line) { - $code .= $this->getIndent() . $line . PHP_EOL; + $code .= $this->getIndent().$line.PHP_EOL; } + return $code; } public function parseExpr(mixed $expr) { $type = $expr->getType(); - $this->writeLog('Line ' . $this->getLine($expr) . ': ' . $type); + $this->writeLog('Line '.$this->getLine($expr).': '.$type); if ($expr->getLine() === $this->debugLine) { dump($expr); } @@ -597,9 +612,11 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseEmpty($expr); case 'Expr_Assign': $result = $this->parseAssign($expr); + return $result; case 'Expr_AssignRef': $result = $this->parseAssignRef($expr); + return $result; case 'Expr_Print': return $this->parsePrint($expr); @@ -768,11 +785,12 @@ class CompilerBase extends \PhpAot\Core\Translator $propName = $this->identifierToStr($left->var->name); $code = ''; $value = $this->trimBrackets($this->parseExpr($right)); - if ($left->dim === null) { - return $code . "$obj.appendArrayProperty($propName, $value)"; + if (null === $left->dim) { + return $code."$obj.appendArrayProperty($propName, $value)"; } else { $dim = $this->trimBrackets($this->parseIdentifier($left->dim)); - return $code . "$obj.updateArrayProperty($propName, $dim, $value)"; + + return $code."$obj.updateArrayProperty($propName, $dim, $value)"; } } @@ -792,11 +810,12 @@ class CompilerBase extends \PhpAot\Core\Translator } $value = $this->trimBrackets($this->parseExpr($right)); - if ($left->dim === null) { - return $code . "$array.offsetSet(php::null, $value)"; + if (null === $left->dim) { + return $code."$array.offsetSet(php::null, $value)"; } else { $dim = $this->trimBrackets($this->parseIdentifier($left->dim)); - return $code . "$array.offsetSet($dim, $value)"; + + return $code."$array.offsetSet($dim, $value)"; } } @@ -804,7 +823,8 @@ class CompilerBase extends \PhpAot\Core\Translator { $array = $this->parseIdentifier($left->var); $propName = $this->identifierToStr($left->name); - return "$array.setProperty($propName, " . $this->trimBrackets($this->parseExpr($right)) . ")"; + + return "$array.setProperty($propName, ".$this->trimBrackets($this->parseExpr($right)).')'; } protected function parseRightAssociativeAssign(NodeAbstract $left, Node\Expr\Assign $right): string @@ -821,7 +841,7 @@ class CompilerBase extends \PhpAot\Core\Translator $checkVarFn($left); $chain[] = $left; $next = $right; - while ($next->getType() === 'Expr_Assign') { + while ('Expr_Assign' === $next->getType()) { $var = $next->var; $checkVarFn($var); $chain[] = $var; @@ -835,12 +855,13 @@ class CompilerBase extends \PhpAot\Core\Translator $chain = array_reverse($chain); $list = []; - $list[] = $this->getIndent() . $tmpVar . ' = ' . $this->parseExpr($next); + $list[] = $this->getIndent().$tmpVar.' = '.$this->parseExpr($next); $right = new Variable($tmpVar); foreach ($chain as $var) { - $list[] = $this->getIndent() . $this->parseFinallyAssign($var, $right); + $list[] = $this->getIndent().$this->parseFinallyAssign($var, $right); } - return implode(";\n" . $this->getIndent(), $list); + + return implode(";\n".$this->getIndent(), $list); } protected function parseAssign(Node\Expr\Assign $v): string @@ -848,16 +869,18 @@ class CompilerBase extends \PhpAot\Core\Translator $left = $v->var; $right = $v->expr; - if ($right->getType() === 'Expr_Assign') { + if ('Expr_Assign' === $right->getType()) { return $this->parseRightAssociativeAssign($left, $right); - } elseif ($left->getType() === self::EXPR_ARRAY_DIM_FETCH) { + } elseif (self::EXPR_ARRAY_DIM_FETCH === $left->getType()) { return $this->parseAssignArrayDim($left, $right); - } elseif ($left->getType() === 'Expr_StaticPropertyFetch') { + } elseif ('Expr_StaticPropertyFetch' === $left->getType()) { $class = $this->identifierToStr($left->class); $propName = $this->identifierToStr($left->name); $value = $this->trimBrackets($this->parseExpr($right)); + return "php::setStaticProperty($class, $propName, $value)"; } + return $this->parseFinallyAssign($left, $right); } @@ -866,10 +889,10 @@ class CompilerBase extends \PhpAot\Core\Translator if ($left instanceof Node\Expr\List_) { $items = $left->items; $code = '{'; - $this->indentLevel++; + ++$this->indentLevel; $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); - $code .= $this->getIndent() . $tmpVar . ' = ' . $this->parseExpr($right) . '; '; + $code .= $this->getIndent().$tmpVar.' = '.$this->parseExpr($right).'; '; foreach ($items as $k => $item) { if (!$item) { continue; @@ -884,14 +907,15 @@ class CompilerBase extends \PhpAot\Core\Translator abort($item); } } - $this->indentLevel--; - return $code . '}'; + --$this->indentLevel; + + return $code.'}'; } $this->inAssignExpr = true; $var = $this->parseIdentifier($left); $this->inAssignExpr = false; - if ($var === 'this_') { + if ('this_' === $var) { $this->fatalError($left, 'Cannot re-assign $this'); } @@ -906,17 +930,18 @@ class CompilerBase extends \PhpAot\Core\Translator $type = self::TYPE_OBJECT; } elseif ($this->isFuncCallExpr($right) and $this->isNameExpr($right->name)) { $fn = $this->parseIdentifier($right->name); - if (count($right->args) === 2 and $fn === 'objval' and $this->isScalarString($right->args[1]->value)) { + if (2 === count($right->args) and 'objval' === $fn and $this->isScalarString($right->args[1]->value)) { $this->objects[$var] = $this->parseIdentifier($right->args[1]->value); $type = self::TYPE_OBJECT; - } elseif (count($right->args) === 1 and $fn === 'any') { + } elseif (1 === count($right->args) and 'any' === $fn) { $type = self::TYPE_VAR; if (!$this->hasVar($var)) { $this->addLocalVar($var, $type); } - return $var . ' = ' . $this->parseIdentifier($right->args[0]->value); + + return $var.' = '.$this->parseIdentifier($right->args[0]->value); } else { - $type = $type === self::TYPE_VOID ? self::TYPE_VAR : $type; + $type = self::TYPE_VOID === $type ? self::TYPE_VAR : $type; } } @@ -926,7 +951,8 @@ class CompilerBase extends \PhpAot\Core\Translator } elseif ($this->isPropertyFetch($left)) { $var = $this->parsePropertyFetch($left, true); } - return $var . ' = ' . $this->convertExprType($expr, $this->detectExprType($left), $this->detectExprType($right)); + + return $var.' = '.$this->convertExprType($expr, $this->detectExprType($left), $this->detectExprType($right)); } protected function parseEcho(mixed $v): string @@ -935,25 +961,26 @@ class CompilerBase extends \PhpAot\Core\Translator if ($expr instanceof Node\Expr\Assign) { $this->fatalError($expr, 'Cannot echo assign expression'); } else { - $lines[] = 'php::echo(' . $this->parseExpr($expr) . ');'; + $lines[] = 'php::echo('.$this->parseExpr($expr).');'; } } - return implode("\n" . $this->getIndent(), $lines); + + return implode("\n".$this->getIndent(), $lines); } protected function isFloatStr(string $str): bool { - return filter_var($str, FILTER_VALIDATE_FLOAT) !== false; + return false !== filter_var($str, FILTER_VALIDATE_FLOAT); } protected function isIntStr(string $str): bool { - return filter_var($str, FILTER_VALIDATE_INT) !== false; + return false !== filter_var($str, FILTER_VALIDATE_INT); } protected function isBoolStr(string $str): bool { - return $str === 'true' || $str === 'false'; + return 'true' === $str || 'false' === $str; } protected function isInternalFunction(string $fname): bool @@ -963,28 +990,29 @@ class CompilerBase extends \PhpAot\Core\Translator protected function isAssignOpConcat(string $op): bool { - return $op === '.='; + return '.=' === $op; } protected function isAssignOpPow(string $op): bool { - return $op === '**='; + return '**=' === $op; } /** - * 尽可能转为数字,优先级 浮点 > 整数 > 字符串 + * 尽可能转为数字,优先级 浮点 > 整数 > 字符串. */ protected function parseNumericIdentifier($expr) { - if ($expr->getType() === 'Scalar_String') { + if ('Scalar_String' === $expr->getType()) { if ($this->isFloatStr($expr->value)) { return floatval($expr->value); } elseif ($this->isIntStr($expr->value)) { return intval($expr->value); - } elseif ($expr->value === '0') { + } elseif ('0' === $expr->value) { return 0; } } + return $this->parseIdentifier($expr); } @@ -997,21 +1025,21 @@ class CompilerBase extends \PhpAot\Core\Translator $leftType = $this->detectExprType($left); $rightType = $this->detectExprType($right); - if ($leftType === self::TYPE_FLOAT) { + if (self::TYPE_FLOAT === $leftType) { $rightExpr = $this->convertExprType($rightExpr, self::TYPE_FLOAT, $rightType); - } elseif ($rightType === self::TYPE_FLOAT) { + } elseif (self::TYPE_FLOAT === $rightType) { $leftExpr = $this->convertExprType($leftExpr, $leftType, self::TYPE_FLOAT); - } elseif ($leftType === self::TYPE_INT) { + } elseif (self::TYPE_INT === $leftType) { $rightExpr = $this->convertExprType($rightExpr, self::TYPE_INT, $rightType); - } elseif ($rightType === self::TYPE_INT) { + } elseif (self::TYPE_INT === $rightType) { $leftExpr = $this->convertExprType($leftExpr, $leftType, self::TYPE_INT); } - if ($op === '%' and !($leftType === self::TYPE_INT and $rightType === self::TYPE_INT)) { - return 'php::math::mod(' . $leftExpr . ', ' . $rightExpr . ')'; + if ('%' === $op and !(self::TYPE_INT === $leftType and self::TYPE_INT === $rightType)) { + return 'php::math::mod('.$leftExpr.', '.$rightExpr.')'; } - return '((' . $leftExpr . ') ' . $op . ' (' . $rightExpr . '))'; + return '(('.$leftExpr.') '.$op.' ('.$rightExpr.'))'; } protected function parseBinaryOpPlus(mixed $expr): string @@ -1021,16 +1049,16 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseReturn(mixed $v): string { - if ($v->expr === null) { + if (null === $v->expr) { return 'return;'; } // 实际函数的返回值 $type = $this->detectExprType($v->expr); $expr = $this->parseExpr($v->expr); // 函数定义时没有声明返回值,但函数体中有返回值,修改为实际的返回值类型 - if ($this->getReturnType() === 'void') { + if ('void' === $this->getReturnType()) { $this->resetReturnType($type); - } elseif ($this->getReturnType() !== self::TYPE_VAR and $this->getReturnType() !== $type) { + } elseif (self::TYPE_VAR !== $this->getReturnType() and $this->getReturnType() !== $type) { // 返回值类型不一致,说明存在多种类型的返回值,修改为 var 表示 any $this->resetReturnType(self::TYPE_VAR); } @@ -1041,11 +1069,12 @@ class CompilerBase extends \PhpAot\Core\Translator $tmpVar = $this->genTmpVarName(); // 必须提前声明变量,否则在末尾声明并 return 可能会被 gcc 优化掉 $this->addLocalVar($tmpVar, $type); - $code = $tmpVar . ' = ' . $exprCode . ';' . PHP_EOL; - $code .= $this->getIndent() . 'return ' . $tmpVar; + $code = $tmpVar.' = '.$exprCode.';'.PHP_EOL; + $code .= $this->getIndent().'return '.$tmpVar; } else { - $code = 'return ' . $exprCode; + $code = 'return '.$exprCode; } + return $code; } @@ -1063,6 +1092,7 @@ class CompilerBase extends \PhpAot\Core\Translator { $index = $this->literalStringIndex++; $this->literalStrings[$value] = $index; + return $index; } @@ -1092,6 +1122,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function detectVarType($var): string { $name = $this->parseIdentifier($var); + return $this->getVarType($name); } @@ -1125,10 +1156,10 @@ class CompilerBase extends \PhpAot\Core\Translator case 'Expr_BinaryOp_BooleanAnd': $leftType = $this->detectExprType($expr->left); $rightType = $this->detectExprType($expr->right); - if ($leftType === self::TYPE_FLOAT || $rightType === self::TYPE_FLOAT) { + if (self::TYPE_FLOAT === $leftType || self::TYPE_FLOAT === $rightType) { return self::TYPE_FLOAT; } - if ($leftType === self::TYPE_INT || $rightType === self::TYPE_INT) { + if (self::TYPE_INT === $leftType || self::TYPE_INT === $rightType) { return self::TYPE_INT; } break; @@ -1137,6 +1168,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isNativeFunction($name)) { return $this->nativeFunctions[$name]->returnType; } + return $this->detectFuncCallReturnType($name); case 'Expr_New': return self::TYPE_OBJECT; @@ -1151,6 +1183,7 @@ class CompilerBase extends \PhpAot\Core\Translator default: break; } + return self::TYPE_VAR; } @@ -1158,8 +1191,8 @@ class CompilerBase extends \PhpAot\Core\Translator { $items = $node->items; // 优化代码风格,空数组直接返回{},否则会产生一些空洞内容 - if (count($items) === 0) { - return self::TYPE_ARRAY .'{}'; + if (0 === count($items)) { + return self::TYPE_ARRAY.'{}'; } $assocArray = false; @@ -1171,7 +1204,7 @@ class CompilerBase extends \PhpAot\Core\Translator } $list = []; - $this->indentLevel++; + ++$this->indentLevel; foreach ($items as $item) { $value = $this->parseIdentifier($item->value); if ($assocArray) { @@ -1179,26 +1212,27 @@ class CompilerBase extends \PhpAot\Core\Translator $key = $item->key ? $this->parseIdentifier($item->key) : 'php::null'; if (str_starts_with($key, self::LITERAL_STRINGS)) { $key = "$key.toStdString()"; - } elseif ($key === '0L') { + } elseif ('0L' === $key) { $key = 'php::zero'; } - $list[] = $this->getIndent() . '{ ' . $key . ', ' . - self::TYPE_VAR . '(' . $value . ') }'; + $list[] = $this->getIndent().'{ '.$key.', '. + self::TYPE_VAR.'('.$value.') }'; } else { - $list[] = $this->getIndent() . self::TYPE_VAR . '(' . $value . ')'; + $list[] = $this->getIndent().self::TYPE_VAR.'('.$value.')'; } } - $this->indentLevel--; - return self::TYPE_ARRAY . '{' . PHP_EOL . - implode(', ' . PHP_EOL, $list) . PHP_EOL . - $this->getIndent() . + --$this->indentLevel; + + return self::TYPE_ARRAY.'{'.PHP_EOL. + implode(', '.PHP_EOL, $list).PHP_EOL. + $this->getIndent(). '}'; } protected function parseParameterType(Node\Param $param, string $var): string { $type = $param->type; - if ($type == null) { + if (null == $type) { return self::TYPE_VAR; } if ($type instanceof NullableType or $type instanceof UnionType) { @@ -1226,6 +1260,7 @@ class CompilerBase extends \PhpAot\Core\Translator break; default: $this->objects[$var] = $name; + return self::TYPE_OBJECT; } } @@ -1233,13 +1268,14 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseIncludes(): string { $list = [ - $this->phpxDir . '/include', - $this->getBuildDir() . '/include', + $this->phpxDir.'/include', + $this->getBuildDir().'/include', ]; $out = '$(php-config --includes) '; foreach ($list as $li) { - $out .= '-I ' . $li . ' '; + $out .= '-I '.$li.' '; } + return $out; } @@ -1247,32 +1283,34 @@ class CompilerBase extends \PhpAot\Core\Translator { $list = [ '$(php-config --prefix)/lib', - $this->phpxDir . '/lib', + $this->phpxDir.'/lib', ]; $out = ''; foreach ($list as $li) { - $out .= '-L ' . $li . ' '; + $out .= '-L '.$li.' '; } + return $out; } protected function parseLibs(): string { $list = ['phpx']; - if ($this->buildMode === 'bin') { + if ('bin' === $this->buildMode) { $list[] = 'php'; } $out = ''; foreach ($list as $li) { - $out .= '-l' . $li . ' '; + $out .= '-l'.$li.' '; } + return $out; } protected function addCompilationOption(string &$cmd, bool $link): void { - $cmd .= ' ' . $this->parseIncludes(); - $cmd .= ' -O' . $this->optimizeLevel; + $cmd .= ' '.$this->parseIncludes(); + $cmd .= ' -O'.$this->optimizeLevel; $cmd .= ' -g'; $cmd .= ' -Wall'; if ($this->enableProfiler) { @@ -1280,7 +1318,7 @@ class CompilerBase extends \PhpAot\Core\Translator $cmd .= ' -DPPROF_ON=1'; } - if ($this->buildMode === 'ext') { + if ('ext' === $this->buildMode) { if ($link) { $cmd .= ' -shared'; } else { @@ -1289,14 +1327,14 @@ class CompilerBase extends \PhpAot\Core\Translator } if ($link) { - $cmd .= ' ' . $this->parseLdflags(); - $cmd .= ' ' . $this->parseLibs(); + $cmd .= ' '.$this->parseLdflags(); + $cmd .= ' '.$this->parseLibs(); if ($this->ldflags) { - $cmd .= ' ' . $this->ldflags; + $cmd .= ' '.$this->ldflags; } } else { if ($this->cxxflags) { - $cmd .= ' ' . $this->cxxflags; + $cmd .= ' '.$this->cxxflags; } } } @@ -1306,7 +1344,7 @@ class CompilerBase extends \PhpAot\Core\Translator $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return 'php::concat(' . $left . ', ' . $right . ')'; + return 'php::concat('.$left.', '.$right.')'; } protected function parseFor(mixed $v): string @@ -1322,11 +1360,11 @@ class CompilerBase extends \PhpAot\Core\Translator $list_expr[] = $this->parseExpr($expr); } $list_expr[] = ''; - $code .= implode(";\n" . $this->getIndent(), $list_expr); + $code .= implode(";\n".$this->getIndent(), $list_expr); $list_cond = []; foreach ($cond as $expr) { - if ($expr->getType() === 'Expr_Assign') { + if ('Expr_Assign' === $expr->getType()) { $left = $expr->var; $name = $this->parseIdentifier($left); $type = $this->detectExprType($expr->expr); @@ -1334,12 +1372,12 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->hasVar($name)) { $this->addLocalVar($name, $type); } - $code .= $name . ' = ' . '(' . $this->parseIdentifier($expr->expr) . ');'; + $code .= $name.' = ('.$this->parseIdentifier($expr->expr).');'; } $list_cond[] = $this->parseExpr($expr); } - $code .= $this->parseBeforeStmtLines() . PHP_EOL; + $code .= $this->parseBeforeStmtLines().PHP_EOL; $code .= 'for (;'; $code .= implode(', ', $list_cond); $code .= '; '; @@ -1349,13 +1387,13 @@ class CompilerBase extends \PhpAot\Core\Translator $list_loop[] = $this->parseExpr($expr); } $code .= implode(', ', $list_loop); - $code .= ') {' . PHP_EOL; + $code .= ') {'.PHP_EOL; - $this->indentLevel++; + ++$this->indentLevel; $code .= $this->parseStmts($stmts); - $this->indentLevel--; + --$this->indentLevel; - $code .= $this->getIndent() . '}' . PHP_EOL; + $code .= $this->getIndent().'}'.PHP_EOL; return $code; } @@ -1367,7 +1405,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePreInc(mixed $expr): string { - return '++' . $this->parseIdentifier($expr->var); + return '++'.$this->parseIdentifier($expr->var); } protected function removeAssignOp(string $op): string @@ -1390,19 +1428,21 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isArrayVar($node->var)) { $this->fatalError($node->var, 'Cannot concat string to array'); } - return $var . '.append(' . $rightExprStr . ')'; + + return $var.'.append('.$rightExprStr.')'; } elseif ($this->isAssignOpPow($op)) { - $powExpr = 'php::call(php::pow, {' . $var . ', ' . $rightExprStr . '})'; - return $var . ' = ' . $this->convertVarType($var, $powExpr); + $powExpr = 'php::call(php::pow, {'.$var.', '.$rightExprStr.'})'; + + return $var.' = '.$this->convertVarType($var, $powExpr); } else { - return $var . ' ' . $op . ' ' . $rightExprStr; + return $var.' '.$op.' '.$rightExprStr; } - } elseif ($leftExprType === self::EXPR_ARRAY_DIM_FETCH) { + } elseif (self::EXPR_ARRAY_DIM_FETCH === $leftExprType) { /** * $count[$r] -= 1; * 需要转为下面语句: * $tmp_var = $count[$r] - 1; - * $count[$r] = $tmp_var; + * $count[$r] = $tmp_var;. */ $type = $this->detectVarType($node->var); $rightType = $this->detectExprType($node->expr); @@ -1411,19 +1451,20 @@ class CompilerBase extends \PhpAot\Core\Translator $dim = $this->parseIdentifier($node->var->dim); $binaryOp = $this->removeAssignOp($op); - if ($binaryOp === '.') { - $this->beforeStmtLines[] = "$tmpVar = php::concat(" . - $this->convertVarType($tmpVar, $var) . ', ' . - $this->convertExprType($expr, $type, $rightType) . ');'; + if ('.' === $binaryOp) { + $this->beforeStmtLines[] = "$tmpVar = php::concat(". + $this->convertVarType($tmpVar, $var).', '. + $this->convertExprType($expr, $type, $rightType).');'; } else { - $this->beforeStmtLines[] = "$tmpVar = " . - $this->convertVarType($tmpVar, $var) . ' ' . - $binaryOp . ' ' . - $this->convertExprType($expr, $type, $rightType) . ';'; + $this->beforeStmtLines[] = "$tmpVar = ". + $this->convertVarType($tmpVar, $var).' '. + $binaryOp.' '. + $this->convertExprType($expr, $type, $rightType).';'; } + return $this->parseArrayDimStore($node->var->var, $dim, $tmpVar); } else { - return $var . ' ' . $op . ' (' . $expr . ')'; + return $var.' '.$op.' ('.$expr.')'; } } @@ -1489,22 +1530,24 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseArrayDimFetch($node, bool $write): string { $var = $this->parseIdentifier($node->var); - if ($node->dim === null) { + if (null === $node->dim) { if (!$write) { $this->fatalError($node, 'Cannot use [] for reading'); } else { - return $var . '.newItem()'; + return $var.'.newItem()'; } } else { $dim = $this->trimBrackets($this->parseIdentifier($node->dim)); - return $var . '.item(' . $dim . ', ' . $this->escapeBool($write) . ')'; + + return $var.'.item('.$dim.', '.$this->escapeBool($write).')'; } } protected function parseArrayDimStore($array, $dim, $var): string { $id = $this->parseIdentifier($array); - return $id . '.offsetSet(' . $this->trimBrackets($dim) . ', ' . $this->trimBrackets($var) . ')'; + + return $id.'.offsetSet('.$this->trimBrackets($dim).', '.$this->trimBrackets($var).')'; } protected function parseBinaryOpShiftLeft($expr): string @@ -1523,18 +1566,18 @@ class CompilerBase extends \PhpAot\Core\Translator } /** - * 查找原生函数 - * @param string $fname + * 查找原生函数. + * * @return bool */ protected function findNativeFunction(string $fname): string|false { - $possibleFunctionNames = [$this->escapeName($fname),]; + $possibleFunctionNames = [$this->escapeName($fname)]; if ($this->namespace) { - $possibleFunctionNames[] = $this->escapeNamespace($this->namespace) . self::NAMESPACE_SEPARATOR . $fname; + $possibleFunctionNames[] = $this->escapeNamespace($this->namespace).self::NAMESPACE_SEPARATOR.$fname; } if (isset($this->useFunctions[$fname])) { - $possibleFunctionNames[] = $this->escapeNamespace($this->useFunctions[$fname]) . self::NAMESPACE_SEPARATOR . $fname; + $possibleFunctionNames[] = $this->escapeNamespace($this->useFunctions[$fname]).self::NAMESPACE_SEPARATOR.$fname; } foreach ($possibleFunctionNames as $name) { // 在预处理阶段检测到函数声明,但是未定义,说明在当前文件,但是顺序错误 @@ -1542,12 +1585,14 @@ class CompilerBase extends \PhpAot\Core\Translator and $this->functionDeclInFile[$name] === $this->file and !$this->isNativeFunction($name)) { $this->redoAfterDeclare[$name] = true; + return $name; } if ($this->isNativeFunction($name)) { return $name; } } + return false; } @@ -1556,19 +1601,19 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isVarExpr($expr->name)) { $fn = $this->parseIdentifier($expr->name); $name = ''; - } elseif ($expr->name->getType() === 'Name') { + } elseif ('Name' === $expr->name->getType()) { $name = $this->parseIdentifier($expr->name); if (in_array($name, $this->unsupportedFunctions)) { - $this->fatalError($expr, 'Unsupported function: `' . $name . '`'); + $this->fatalError($expr, 'Unsupported function: `'.$name.'`'); } $nativeFn = $this->findNativeFunction($name); if ($nativeFn) { - return self::PREFIX . $nativeFn . '(' . $this->parseNativeCallArgs($expr->args, $nativeFn) . ')'; + return self::PREFIX.$nativeFn.'('.$this->parseNativeCallArgs($expr->args, $nativeFn).')'; } if ($this->isInternalFunction($name)) { - $fn = 'php::' . $name; + $fn = 'php::'.$name; } else { - $fn = '"' . $name . '"'; + $fn = '"'.$name.'"'; } $code = $this->parseFuncCallWithOptimizer($name, $expr); if ($code) { @@ -1577,15 +1622,15 @@ class CompilerBase extends \PhpAot\Core\Translator } else { $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); - $this->beforeStmtLines[] = $tmpVar . ' = ' . $this->parseExpr($expr->name) . ';'; + $this->beforeStmtLines[] = $tmpVar.' = '.$this->parseExpr($expr->name).';'; $fn = $tmpVar; $name = ''; } $call = $silent ? 'php::silentCall' : 'php::call'; if (empty($expr->args)) { - return $call . '(' . $fn . ')'; + return $call.'('.$fn.')'; } else { - return $call . '(' . $fn . ', {' . $this->parseCallArgs($expr->args, $name) . '})'; + return $call.'('.$fn.', {'.$this->parseCallArgs($expr->args, $name).'})'; } } @@ -1596,6 +1641,7 @@ class CompilerBase extends \PhpAot\Core\Translator $argInfo = $this->getArgInfo($arg, $nativeFunc, $i); $list_args[] = $this->getTypeConvertedArg($arg, $argInfo); } + return implode(', ', $list_args); } @@ -1614,28 +1660,29 @@ class CompilerBase extends \PhpAot\Core\Translator // 调用了不存在的变量,可能是引用 if (!$this->hasVar($name)) { $this->addLocalVar($name, self::TYPE_REF); - $this->beforeStmtLines[] = $name . ' = php::newReference();'; + $this->beforeStmtLines[] = $name.' = php::newReference();'; } elseif ($funcName and Reflection::isReferenceArg($funcName, $i)) { // 需要引用类型的参数,使用临时变量作为引用,并替换掉实际的参数 $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_REF); - $this->beforeStmtLines[] = $tmpVar . ' = ' . $this->parseExpr($arg->value) . '.toReference();'; - $list_args[] = '&' . $tmpVar; + $this->beforeStmtLines[] = $tmpVar.' = '.$this->parseExpr($arg->value).'.toReference();'; + $list_args[] = '&'.$tmpVar; continue; } } elseif ($this->isPropertyFetch($arg->value)) { if ($funcName and Reflection::isReferenceArg($funcName, $i)) { $obj = $this->parseIdentifier($arg->value->var); - $list_args[] = $obj . '.getPropertyReference(' . $this->identifierToStr($arg->value->name) . ')'; + $list_args[] = $obj.'.getPropertyReference('.$this->identifierToStr($arg->value->name).')'; continue; } } // 不支持变长参数展开的语法,例如:array_merge(...$arr) if ($arg->unpack) { - $this->fatalError($arg, "The syntax for variable parameter expansion is not supported"); + $this->fatalError($arg, 'The syntax for variable parameter expansion is not supported'); } $list_args[] = $this->parseArg($arg); } + return implode(', ', $list_args); } @@ -1647,25 +1694,27 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePostOp($expr, string $op): string { if ($this->isVarExpr($expr->var)) { - return $this->parseIdentifier($expr->var) . str_repeat($op, 2); + return $this->parseIdentifier($expr->var).str_repeat($op, 2); } elseif ($this->isPropertyFetch($expr->var)) { $obj = $this->parseIdentifier($expr->var->var); $prop = $this->identifierToStr($expr->var->name); $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); - $this->beforeStmtLines[] = $tmpVar . ' = ' . $obj. '.getProperty(' . $prop . ');'; - $this->afterStmtLines[] = $obj . '.setProperty(' . $prop . ', ' . $tmpVar . ' ' . $op . ' 1);'; + $this->beforeStmtLines[] = $tmpVar.' = '.$obj.'.getProperty('.$prop.');'; + $this->afterStmtLines[] = $obj.'.setProperty('.$prop.', '.$tmpVar.' '.$op.' 1);'; + return $tmpVar; } elseif ($this->isStaticPropertyFetch($expr->var)) { $class = $this->identifierToStr($expr->var->class); $prop = $this->identifierToStr($expr->var->name); $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); - $this->beforeStmtLines[] = $tmpVar . ' = ' . 'php::getStaticProperty(' . $class . ', ' . $prop . ');'; - $this->afterStmtLines[] = 'php::setStaticProperty(' . $class . ', ' . $prop . ', ' . $tmpVar . ' ' . $op . ' 1);'; + $this->beforeStmtLines[] = $tmpVar.' = php::getStaticProperty('.$class.', '.$prop.');'; + $this->afterStmtLines[] = 'php::setStaticProperty('.$class.', '.$prop.', '.$tmpVar.' '.$op.' 1);'; + return $tmpVar; } - $this->fatalError($expr, "Post-increment operator is not supported for non-variable expressions"); + $this->fatalError($expr, 'Post-increment operator is not supported for non-variable expressions'); } protected function parsePostDec($expr): string @@ -1683,11 +1732,12 @@ class CompilerBase extends \PhpAot\Core\Translator $cond = $expr->cond; $if = $expr->if; $else = $expr->else; - if ($if === null) { + if (null === $if) { $cond = $this->parseExpr($cond); - return '(' . $cond . ') ? (' . $cond . ') : (' . $this->parseExpr($else) . ')'; + + return '('.$cond.') ? ('.$cond.') : ('.$this->parseExpr($else).')'; } else { - return '(' . $this->parseExpr($cond) . ') ? (' . $this->parseExpr($if) . ') : (' . $this->parseExpr($else) . ')'; + return '('.$this->parseExpr($cond).') ? ('.$this->parseExpr($if).') : ('.$this->parseExpr($else).')'; } } @@ -1701,12 +1751,12 @@ class CompilerBase extends \PhpAot\Core\Translator $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return 'php::pow(' . $left . ', ' . $right . ')'; + return 'php::pow('.$left.', '.$right.')'; } protected function parsePreDec(mixed $expr): string { - return '--' . $this->parseIdentifier($expr->var); + return '--'.$this->parseIdentifier($expr->var); } protected function parseBinaryOpBitwiseAnd(mixed $expr): string @@ -1727,54 +1777,55 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseBitwiseNot(mixed $expr): string { $var = $this->parseIdentifier($expr->expr); - return '~' . $var; + + return '~'.$var; } protected function parseIf(mixed $v): string { $cond = $this->parseExpr($v->cond); - $code = $this->parseBeforeStmtLines() . PHP_EOL; - $code .= 'if (' . $cond . ') {' . PHP_EOL; - $this->indentLevel++; + $code = $this->parseBeforeStmtLines().PHP_EOL; + $code .= 'if ('.$cond.') {'.PHP_EOL; + ++$this->indentLevel; $code .= $this->parseStmts($v->stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}'; + --$this->indentLevel; + $code .= $this->getIndent().'}'; if ($v->elseifs) { foreach ($v->elseifs as $elseif) { $elseifCond = $this->parseExpr($elseif->cond); - $code .= ' else if (' . $elseifCond . ') {' . PHP_EOL; - $this->indentLevel++; + $code .= ' else if ('.$elseifCond.') {'.PHP_EOL; + ++$this->indentLevel; $code .= $this->parseStmts($elseif->stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}'; + --$this->indentLevel; + $code .= $this->getIndent().'}'; } } if ($v->else) { - $code .= ' else {' . PHP_EOL; - $this->indentLevel++; + $code .= ' else {'.PHP_EOL; + ++$this->indentLevel; $code .= $this->parseStmts($v->else->stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}'; + --$this->indentLevel; + $code .= $this->getIndent().'}'; } - return $code . PHP_EOL; + return $code.PHP_EOL; } protected function parseBinaryOpEqual(mixed $expr): string { - return 'php::equals(' . $this->parseExpr($expr->left) . ', ' . $this->parseExpr($expr->right) . ')'; + return 'php::equals('.$this->parseExpr($expr->left).', '.$this->parseExpr($expr->right).')'; } protected function parseBinaryOpNotEqual(mixed $expr): string { - return '!php::equals(' . $this->parseExpr($expr->left) . ', ' . $this->parseExpr($expr->right) . ')'; + return '!php::equals('.$this->parseExpr($expr->left).', '.$this->parseExpr($expr->right).')'; } /** - * 逻辑比较的运算,必须返回 bool 类型 + * 逻辑比较的运算,必须返回 bool 类型. */ protected function parseBinaryOpLogicalAnd(Node $expr): string { @@ -1794,7 +1845,8 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseBooleanNot(Node $expr): string { $expr = $this->parseExpr($expr->expr); - return '!' . $expr; + + return '!'.$expr; } protected function parseWhile(Node $v): string @@ -1802,25 +1854,25 @@ class CompilerBase extends \PhpAot\Core\Translator $cond = $this->parseExpr($v->cond); $stmts = $v->stmts; - $code = $this->parseBeforeStmtLines() . PHP_EOL; - $code .= 'while (' . $cond . ') {' . PHP_EOL; - $this->indentLevel++; + $code = $this->parseBeforeStmtLines().PHP_EOL; + $code .= 'while ('.$cond.') {'.PHP_EOL; + ++$this->indentLevel; $code .= $this->parseStmts($stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}' . PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'}'.PHP_EOL; return $code; } public function isClosedCall($expr, $call): bool { - if ($call === '') { + if ('' === $call) { if (!str_starts_with($expr, '(')) { return false; } $startPos = 0; } else { - if (!str_starts_with($expr, $call . '(')) { + if (!str_starts_with($expr, $call.'(')) { return false; } $startPos = strlen($call); @@ -1829,17 +1881,18 @@ class CompilerBase extends \PhpAot\Core\Translator $bracketCount = 0; $length = strlen($expr); - for ($i = $startPos; $i < $length; $i++) { + for ($i = $startPos; $i < $length; ++$i) { $char = $expr[$i]; - if ($char === '(') { - $bracketCount++; - } elseif ($char === ')') { - $bracketCount--; - if ($bracketCount === 0) { + if ('(' === $char) { + ++$bracketCount; + } elseif (')' === $char) { + --$bracketCount; + if (0 === $bracketCount) { return $i === $length - 1; } } } + return false; } @@ -1848,64 +1901,71 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isClosedCall($str, '')) { return substr($str, 1, -1); } + return $str; } protected function convertIntExpr(string $expr): string { if (!$this->isClosedCall($expr, 'php::toInt')) { - return 'php::toInt(' . $this->trimBrackets($expr) . ')'; + return 'php::toInt('.$this->trimBrackets($expr).')'; } + return $expr; } protected function convertFloatExpr(string $expr): string { if (!$this->isClosedCall($expr, 'php::toFloat')) { - return 'php::toFloat(' . $this->trimBrackets($expr) . ')'; + return 'php::toFloat('.$this->trimBrackets($expr).')'; } + return $expr; } public function stop(string $string): void { - $this->climate->red($string . "\n"); + $this->climate->red($string."\n"); exit(1); } protected function convertStringExpr(string $expr): string { if (!$this->isClosedCall($expr, 'php::toString')) { - return 'php::toString(' . $this->trimBrackets($expr) . ')'; + return 'php::toString('.$this->trimBrackets($expr).')'; } + return $expr; } protected function convertObjectExpr(string $expr, string $class = ''): string { if (!$this->isClosedCall($expr, 'php::toObject')) { - if ($class === '') { - return 'php::toObject(' . $this->trimBrackets($expr) . ')'; + if ('' === $class) { + return 'php::toObject('.$this->trimBrackets($expr).')'; } else { - return 'php::toObject(' . $this->trimBrackets($expr) . ', ' . $class . ')'; + return 'php::toObject('.$this->trimBrackets($expr).', '.$class.')'; } } + return $expr; } protected function convertArrayExpr(string $expr): string { if (!$this->isClosedCall($expr, 'php::toArray')) { - return 'php::toArray(' . $this->trimBrackets($expr) . ')'; + return 'php::toArray('.$this->trimBrackets($expr).')'; } + return $expr; } protected function convertBoolExpr(string $expr): string { if (!$this->isClosedCall($expr, 'php::toBool')) { - return 'php::toBool(' . $this->trimBrackets($expr) . ')'; + return 'php::toBool('.$this->trimBrackets($expr).')'; } + return $expr; } @@ -1921,19 +1981,19 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePrint(Node\Expr\Print_ $expr): string { - return 'php::echo(' . $this->parseExpr($expr->expr) . ')'; + return 'php::echo('.$this->parseExpr($expr->expr).')'; } protected function parseDo(Node\Stmt\Do_ $v): string { $stmts = $v->stmts; $cond = $this->parseExpr($v->cond); - $code = $this->parseBeforeStmtLines() . PHP_EOL; - $code .= 'do {' . PHP_EOL; - $this->indentLevel++; + $code = $this->parseBeforeStmtLines().PHP_EOL; + $code .= 'do {'.PHP_EOL; + ++$this->indentLevel; $code .= $this->parseStmts($stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '} while (' . $cond . ');' . PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'} while ('.$cond.');'.PHP_EOL; return $code; } @@ -1943,46 +2003,50 @@ class CompilerBase extends \PhpAot\Core\Translator $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - if ($right === 'nullptr') { - return $left . '.isNull()'; + if ('nullptr' === $right) { + return $left.'.isNull()'; } - return 'php::same(' . $left . ', ' . $right . ')'; + return 'php::same('.$left.', '.$right.')'; } protected function parseBinaryOpSpaceship(Node\Expr\BinaryOp\Spaceship $expr): string { $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return 'php::compare(' . $left . ', ' . $right . ')'; + + return 'php::compare('.$left.', '.$right.')'; } protected function parseBinaryOpNotIdentical(Node\Expr\BinaryOp $expr): string { - return '!(' . $this->parseBinaryOpIdentical($expr) . ')'; + return '!('.$this->parseBinaryOpIdentical($expr).')'; } protected function parseNew(Node\Expr\New_ $expr): string { $className = $this->parseIdentifier($expr->class); $args = $expr->args; + $cePtr = $this->getClassEntryPtr($className); if (empty($args)) { - return 'php::newObject("' . $className . '")'; + return 'php::newObject('.$cePtr.')'; } else { - return 'php::newObject("' . $className . '", ' . $this->parseCallArgs($args) . ')'; + return 'php::newObject('.$cePtr.', {'.$this->parseCallArgs($args).'})'; } } protected function parseClone(Node\Expr\Clone_ $expr): string { $var = $this->parseIdentifier($expr->expr); - return $var . '.clone()'; + + return $var.'.clone()'; } protected function parseInstanceof(Node\Expr\Instanceof_ $expr): string { $var = $this->parseIdentifier($expr->expr); - return $var . '.instanceOf(' . $this->identifierToStr($expr->class) . ')'; + + return $var.'.instanceOf('.$this->identifierToStr($expr->class).')'; } protected function parseCastInt(Node\Expr\Cast\Int_ $node): string @@ -2007,29 +2071,31 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseConstFetch(Node\Expr\ConstFetch $expr): string { - if ($expr->name->getType() != 'Name' and !($expr->name instanceof Node\Name\FullyQualified)) { + if ('Name' != $expr->name->getType() and !($expr->name instanceof Node\Name\FullyQualified)) { abort($expr); } $name = $this->parseIdentifier($expr->name); if ($this->hasConstant($name)) { return $this->getConstant($name); } - if ($name === 'null') { + if ('null' === $name) { return 'php::null'; - } elseif ($name === 'true') { + } elseif ('true' === $name) { return 'true'; - } elseif ($name === 'false') { + } elseif ('false' === $name) { return 'false'; - } elseif ($name === 'PHP_EOL') { - return '"' . $this->escapeString(PHP_EOL) . '"'; + } elseif ('PHP_EOL' === $name) { + return '"'.$this->escapeString(PHP_EOL).'"'; } - return 'php::constant("' . $name . '")'; + + return 'php::constant("'.$name.'")'; } protected function parseUnaryMinus(Node $expr): string { $code = $this->parseExpr($expr->expr); - return '-' . $code; + + return '-'.$code; } protected function parseUnaryPlus(mixed $expr) @@ -2041,8 +2107,10 @@ class CompilerBase extends \PhpAot\Core\Translator { $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return $left . ' / (' . $right . ')'; + + return $left.' / ('.$right.')'; } + protected function parseBinaryOpMinus(Node\Expr\BinaryOp\Minus $expr): string { return $this->parseBinaryOp($expr->left, $expr->right, '-'); @@ -2055,7 +2123,8 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($parts as $part) { $list[] = $this->parseExpr($part); } - return 'php::concat({' . implode(', ', $list) . '})'; + + return 'php::concat({'.implode(', ', $list).'})'; } protected function escapeString(string $str): string @@ -2071,8 +2140,8 @@ class CompilerBase extends \PhpAot\Core\Translator protected function escapeVarName(string $name): string { if (in_array($name, Constants::CPP_RESERVED_NAMES)) { - return '_php__var__' . $name; - } elseif ($name === 'this') { + return '_php__var__'.$name; + } elseif ('this' === $name) { return 'this_'; } else { return $name; @@ -2101,7 +2170,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseInterpolatedStringPart(Node $expr): string { - return '"' . $this->escapeString($expr->value) . '"'; + return '"'.$this->escapeString($expr->value).'"'; } protected function parseGlobal(Node $v): string @@ -2112,6 +2181,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->addGlobalVar($name, self::TYPE_VAR); } } + return ''; } @@ -2121,6 +2191,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (!array_key_exists($index, $funcDef->argInfoList)) { $this->fatalError($arg, "Argument `$index` of function `$funcName` not found"); } + return $funcDef->argInfoList[$index]; } @@ -2133,26 +2204,28 @@ class CompilerBase extends \PhpAot\Core\Translator { $expr = $this->parseArg($arg); $type = $this->detectExprType($arg->value); + return $this->convertExprType($expr, $argInfo->type, $type); } protected function convertExprType(string $expr, $leftType, $rightType): string { - if ($leftType === self::TYPE_FLOAT or $rightType === self::TYPE_FLOAT) { + if (self::TYPE_FLOAT === $leftType or self::TYPE_FLOAT === $rightType) { return $this->convertFloatExpr($expr); } - if ($leftType === self::TYPE_INT or $rightType === self::TYPE_INT) { + if (self::TYPE_INT === $leftType or self::TYPE_INT === $rightType) { return $this->convertIntExpr($expr); } - if ($leftType === self::TYPE_BOOL or $rightType === self::TYPE_BOOL) { + if (self::TYPE_BOOL === $leftType or self::TYPE_BOOL === $rightType) { return $this->convertBoolExpr($expr); } + return $expr; } protected function parseExit(Node $node): string { - return 'php::exit(' . $this->parseIdentifier($node->expr) . ')'; + return 'php::exit('.$this->parseIdentifier($node->expr).')'; } protected function parseUnset(Node\Stmt\Unset_ $node): string @@ -2161,22 +2234,23 @@ class CompilerBase extends \PhpAot\Core\Translator $lines = []; foreach ($vars as $var) { $type = $var->getType(); - if ($type === self::EXPR_ARRAY_DIM_FETCH) { + if (self::EXPR_ARRAY_DIM_FETCH === $type) { $array = $this->parseIdentifier($var->var); $dim = $this->parseIdentifier($var->dim); - $lines[] = $array . '.offsetUnset(' . $dim . ');'; - } elseif ($type === 'Expr_PropertyFetch') { + $lines[] = $array.'.offsetUnset('.$dim.');'; + } elseif ('Expr_PropertyFetch' === $type) { $object = $this->parseIdentifier($var->var); $propName = $this->parseIdentifier($var->name); - $lines[] = $object . '.unsetProperty("' . $propName . '");'; - } elseif ($type === self::EXPR_VARIABLE) { + $lines[] = $object.'.unsetProperty("'.$propName.'");'; + } elseif (self::EXPR_VARIABLE === $type) { $name = $this->parseIdentifier($var); $lines[] = "$name.unset();"; } else { abort($var); } } - return implode(PHP_EOL . $this->getIndent(), $lines); + + return implode(PHP_EOL.$this->getIndent(), $lines); } protected function getPropertyIdentifier(NodeAbstract $object, NodeAbstract $property): string @@ -2185,8 +2259,8 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isVarExpr($object) and $this->isIdExpr($property)) { $objectName = $this->parseIdentifier($object); $propertyName = $this->parseIdentifier($property); - if ($objectName === 'this_') { - $id = self::PREFIX . $this->getPropertyOffset($propertyName, $this->class, $this->namespace); + if ('this_' === $objectName) { + $id = self::PREFIX.$this->getPropertyOffset($propertyName, $this->class, $this->namespace); } elseif ($this->isTypedObject($objectName)) { $class = $this->objects[$objectName]; if (isset($this->classes[$class])) { @@ -2194,7 +2268,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($classDef->hasProperty($propertyName)) { $propertyDef = $classDef->getProperty($propertyName); if ($propertyDef->isPublic() or $this->class === $class) { - $id = self::PREFIX . $this->getPropertyOffset($propertyName, $class, $classDef->namespace); + $id = self::PREFIX.$this->getPropertyOffset($propertyName, $class, $classDef->namespace); } else { $this->fatalError($property, "Cannot access private/protected property `$propertyName` of class `$class`"); } @@ -2202,6 +2276,7 @@ class CompilerBase extends \PhpAot\Core\Translator } } } + return $id; } @@ -2210,7 +2285,8 @@ class CompilerBase extends \PhpAot\Core\Translator $object = $expr->var; $property = $expr->name; $id = $this->getPropertyIdentifier($object, $property); - return $this->convertToObject($object) . '.attr(' . $id . ', ' . $this->escapeBool($update) . ')'; + + return $this->convertToObject($object).'.attr('.$id.', '.$this->escapeBool($update).')'; } protected function parseAssignOpShiftRight(Node $node): string @@ -2227,17 +2303,17 @@ class CompilerBase extends \PhpAot\Core\Translator { switch ($expr->getType()) { case 'Scalar_MagicConst_Dir': - return '"' . $this->escapeString($this->dir) . '"'; + return '"'.$this->escapeString($this->dir).'"'; case 'Scalar_MagicConst_File': - return '"' . $this->escapeString($this->file) . '"'; + return '"'.$this->escapeString($this->file).'"'; case 'Scalar_MagicConst_Line': - return (string)$expr->getStartLine(); + return (string) $expr->getStartLine(); case 'Scalar_MagicConst_Function': - return '"' . $this->escapeString($this->function) . '"'; + return '"'.$this->escapeString($this->function).'"'; case 'Scalar_MagicConst_Class': - return '"' . $this->escapeString($this->class) . '"'; + return '"'.$this->escapeString($this->class).'"'; case 'Scalar_MagicConst_Method': - return '"' . $this->escapeString($this->class) . '::' . $this->escapeString($this->method) . '"'; + return '"'.$this->escapeString($this->class).'::'.$this->escapeString($this->method).'"'; default: abort($expr); } @@ -2249,33 +2325,33 @@ class CompilerBase extends \PhpAot\Core\Translator $keyVar = $this->parseIdentifier($node->keyVar); } - $code = 'for (auto iter = ' . $iteratorVar . '.begin(); iter != ' . $iteratorVar . '.end(); ++iter) {' . PHP_EOL; - $this->indentLevel++; + $code = 'for (auto iter = '.$iteratorVar.'.begin(); iter != '.$iteratorVar.'.end(); ++iter) {'.PHP_EOL; + ++$this->indentLevel; if ($node->keyVar) { $this->checkVar($node, $keyVar); - $code .= $this->getIndent() . ' ' . $keyVar . ' = iter.key();' . PHP_EOL; + $code .= $this->getIndent().' '.$keyVar.' = iter.key();'.PHP_EOL; } - if ($node->valueVar->getType() == self::EXPR_ARRAY_DIM_FETCH) { + if (self::EXPR_ARRAY_DIM_FETCH == $node->valueVar->getType()) { $array = $this->parseIdentifier($node->valueVar->var); - if (!$this->hasVar($array) or $node->valueVar->dim === null) { + if (!$this->hasVar($array) or null === $node->valueVar->dim) { abort($node->valueVar); } $dim = $this->parseIdentifier($node->valueVar->dim); - $code .= $this->getIndent() . "$array.offsetSet($dim, iter.value());"; + $code .= $this->getIndent()."$array.offsetSet($dim, iter.value());"; } else { $valueVar = $this->parseIdentifier($node->valueVar); $this->checkVar($node, $valueVar); - $code .= $this->getIndent() . ' ' . $valueVar . ' = iter.value();' . PHP_EOL; + $code .= $this->getIndent().' '.$valueVar.' = iter.value();'.PHP_EOL; } $body = $this->parseStmts($node->stmts); - $this->indentLevel--; + --$this->indentLevel; - $code .= $this->parseBeforeStmtLines() . PHP_EOL; - $code .= $body . PHP_EOL; + $code .= $this->parseBeforeStmtLines().PHP_EOL; + $code .= $body.PHP_EOL; - $code .= $this->getIndent() . '}'; + $code .= $this->getIndent().'}'; return $code; } @@ -2289,7 +2365,7 @@ class CompilerBase extends \PhpAot\Core\Translator $name = $this->parseIdentifier($node->expr); if ($this->hasVar($name)) { $type = $this->getVarType($name); - if ($type === self::TYPE_OBJECT) { + if (self::TYPE_OBJECT === $type) { return $this->parseForeachObject($node); } } @@ -2299,8 +2375,8 @@ class CompilerBase extends \PhpAot\Core\Translator $code = ''; $expr = $this->parseIdentifier($node->expr); - $code .= self::TYPE_ARRAY . " $iteratorVar = " . $expr . ';' . PHP_EOL; - $code .= $this->parseBeforeStmtLines() . PHP_EOL; + $code .= self::TYPE_ARRAY." $iteratorVar = ".$expr.';'.PHP_EOL; + $code .= $this->parseBeforeStmtLines().PHP_EOL; $code .= $this->parseForeachArray($node, $iteratorVar); return $code; @@ -2308,15 +2384,15 @@ class CompilerBase extends \PhpAot\Core\Translator protected function formatCppCode(string $file): void { - $cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file; - $this->climate->info('format: ' . $file ); + $cmd = 'cd '.$this->rootPath.' && clang-format -i '.$file; + $this->climate->info('format: '.$file); $this->climate->comment($cmd); shell_exec($cmd); } public function genTmpVarName(): string { - return 'tmp_var_' . $this->tmpVarIndex++; + return 'tmp_var_'.$this->tmpVarIndex++; } protected function detectConstType($expr): string @@ -2325,15 +2401,16 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->hasConstant($name)) { return $this->getConstantType($name); } - if ($name === 'true') { + if ('true' === $name) { return self::TYPE_BOOL; } - if ($name === 'false') { + if ('false' === $name) { return self::TYPE_BOOL; } - if ($name === 'NAN' or $name === 'INF') { + if ('NAN' === $name or 'INF' === $name) { return self::TYPE_FLOAT; } + return self::TYPE_VAR; } @@ -2342,53 +2419,55 @@ class CompilerBase extends \PhpAot\Core\Translator $cond = $v->cond; $tmp_var = $this->genTmpVarName(); $type = $this->detectExprType($cond); - $var_def = $type . ' ' . $tmp_var . ' = ' . $this->parseExpr($cond) . ';' . PHP_EOL; + $var_def = $type.' '.$tmp_var.' = '.$this->parseExpr($cond).';'.PHP_EOL; // 保存作用域,switch 可能会解析失败,在这个过程中会增加变量,需重置 $localVars = $this->localVars; - $code = $this->parseBeforeStmtLines() . PHP_EOL; + $code = $this->parseBeforeStmtLines().PHP_EOL; - if ($type === self::TYPE_INT or $type === self::TYPE_FLOAT) { - $code .= 'switch (' . $tmp_var . ') {' . PHP_EOL; - $this->indentLevel++; + if (self::TYPE_INT === $type or self::TYPE_FLOAT === $type) { + $code .= 'switch ('.$tmp_var.') {'.PHP_EOL; + ++$this->indentLevel; foreach ($v->cases as $case) { if (empty($case->cond)) { - $code .= $this->getIndent() . 'default: {' . PHP_EOL; + $code .= $this->getIndent().'default: {'.PHP_EOL; } else { $condType = $case->cond->getType(); - if ($condType !== 'Scalar_Int' and $condType !== 'Scalar_Float') { + if ('Scalar_Int' !== $condType and 'Scalar_Float' !== $condType) { $this->localVars = $localVars; goto _fail; } - $code .= $this->getIndent() . 'case ' . $this->parseScalar($case->cond) . ': {' . PHP_EOL; + $code .= $this->getIndent().'case '.$this->parseScalar($case->cond).': {'.PHP_EOL; } - $this->indentLevel++; + ++$this->indentLevel; $code .= $this->parseStmts($case->stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}' . PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'}'.PHP_EOL; } - $this->indentLevel--; - $code .= $this->getIndent() . '}'; - return $var_def . $code; + --$this->indentLevel; + $code .= $this->getIndent().'}'; + + return $var_def.$code; } _fail: - $code = 'do {' . PHP_EOL; - $this->indentLevel++; + $code = 'do {'.PHP_EOL; + ++$this->indentLevel; foreach ($v->cases as $case) { if (empty($case->cond)) { - $code .= $this->getIndent() . 'else {' . PHP_EOL; + $code .= $this->getIndent().'else {'.PHP_EOL; } else { - $code .= $this->getIndent() . 'if (' . $tmp_var.'=='. $this->parseIdentifier($case->cond) . ') {' . PHP_EOL; + $code .= $this->getIndent().'if ('.$tmp_var.'=='.$this->parseIdentifier($case->cond).') {'.PHP_EOL; } - $this->indentLevel++; + ++$this->indentLevel; $code .= $this->parseStmts($case->stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}' . PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'}'.PHP_EOL; } - $this->indentLevel--; - $code .= $this->getIndent() . '} while (0);'; - return $var_def . $code; + --$this->indentLevel; + $code .= $this->getIndent().'} while (0);'; + + return $var_def.$code; } protected function parseStatic(mixed $v): string @@ -2397,17 +2476,18 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($v->vars as $var) { if ($var->default) { $type = $this->detectExprType($var->default); - $list[] = 'static ' . $type . ' ' . $this->parseIdentifier($var->var) . ' = ' . $this->parseIdentifier($var->default) . ';'; + $list[] = 'static '.$type.' '.$this->parseIdentifier($var->var).' = '.$this->parseIdentifier($var->default).';'; } else { - $list[] = 'static ' . self::TYPE_VAR . ' ' . $this->parseIdentifier($var->var) . ';'; + $list[] = 'static '.self::TYPE_VAR.' '.$this->parseIdentifier($var->var).';'; } } - return implode(PHP_EOL . $this->getIndent(), $list); + + return implode(PHP_EOL.$this->getIndent(), $list); } protected function parseEval(mixed $expr): string { - return 'php::eval(' . $this->parseIdentifier($expr->expr) . ')'; + return 'php::eval('.$this->parseIdentifier($expr->expr).')'; } protected function parseInclude(Node\Expr\Include_ $expr): string @@ -2428,7 +2508,8 @@ class CompilerBase extends \PhpAot\Core\Translator default: $this->fatalError($expr, 'Invalid include type'); } - return 'php::include(' . $this->parseIdentifier($expr->expr) . ', '. $type . ')'; + + return 'php::include('.$this->parseIdentifier($expr->expr).', '.$type.')'; } protected function parseBreak(mixed $v): string @@ -2443,6 +2524,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->fatalError($v, 'Cannot break more than 1 level'); } } + return 'break;'; } @@ -2453,11 +2535,11 @@ class CompilerBase extends \PhpAot\Core\Translator if (is_nan($value)) { return self::VALUE_NAN; } elseif (is_infinite($value)) { - return $value > 0 ? self::VALUE_INF : '-' . self::VALUE_INF; + return $value > 0 ? self::VALUE_INF : '-'.self::VALUE_INF; } elseif (floor($value) == $value && abs($value) < 1e15) { return number_format($value, 1, '.', ''); } else { - return sprintf('%.' . $this->floatPrecision . 'g', $value); + return sprintf('%.'.$this->floatPrecision.'g', $value); } } @@ -2465,16 +2547,17 @@ class CompilerBase extends \PhpAot\Core\Translator { $vars = $expr->vars; foreach ($vars as $var) { - if ($var instanceof Node\Expr\Variable) { + if ($var instanceof Variable) { return $this->hasVar($var->name) ? 'true' : 'false'; } elseif ($var instanceof Node\Expr\ArrayDimFetch) { - return $this->parseIdentifier($var->var) . ".offsetExists(" . $this->parseIdentifier($var->dim) . ')'; + return $this->parseIdentifier($var->var).'.offsetExists('.$this->parseIdentifier($var->dim).')'; } elseif ($var instanceof Node\Expr\StaticPropertyFetch) { - return 'php::hasStaticProperty(' . $this->identifierToStr($var->class) . ', ' . $this->identifierToStr($var->name) . ')'; + return 'php::hasStaticProperty('.$this->identifierToStr($var->class).', '.$this->identifierToStr($var->name).')'; } elseif ($var instanceof Node\Expr\PropertyFetch) { $object = $var->var; $prop = $var->name; - return $this->parseIdentifier($object) . '.propertyExists(' . $this->identifierToStr($prop) . ')'; + + return $this->parseIdentifier($object).'.propertyExists('.$this->identifierToStr($prop).')'; } else { abort($var); } @@ -2483,7 +2566,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseEmpty(mixed $expr): string { - return 'php::empty(' . $this->parseExpr($expr->expr) . ')'; + return 'php::empty('.$this->parseExpr($expr->expr).')'; } protected function parseCastArray(mixed $expr): string @@ -2513,15 +2596,16 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertExprFromType(string $type, string $expr): string { - if ($type === self::TYPE_FLOAT) { + if (self::TYPE_FLOAT === $type) { return $this->convertFloatExpr($expr); } - if ($type === self::TYPE_INT) { + if (self::TYPE_INT === $type) { return $this->convertIntExpr($expr); } - if ($type === self::TYPE_BOOL) { + if (self::TYPE_BOOL === $type) { return $this->convertBoolExpr($expr); } + return $expr; } @@ -2530,13 +2614,14 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->hasVar($var)) { return $this->convertExprFromType($this->getVarType($var), $expr); } + return $expr; } protected function convertToObject(NodeAbstract $object): string { $id = $this->parseIdentifier($object); - if ($this->isVarExpr($object) and $this->getVarType($id) === self::TYPE_OBJECT) { + if ($this->isVarExpr($object) and self::TYPE_OBJECT === $this->getVarType($id)) { return $id; } @@ -2546,8 +2631,9 @@ class CompilerBase extends \PhpAot\Core\Translator $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_OBJECT); - $this->beforeStmtLines[] = $this->getIndent() . $tmpVar . ' = ' . $id . ';'; + $this->beforeStmtLines[] = $this->getIndent().$tmpVar.' = '.$id.';'; $this->objectWrappers[$id] = $tmpVar; + return $tmpVar; } @@ -2561,19 +2647,20 @@ class CompilerBase extends \PhpAot\Core\Translator $this->addLocalVar($left, self::TYPE_REF); } else { $type = $this->getVarType($left); - if ($type !== self::TYPE_REF) { - $this->fatalError($expr, 'Cannot assign reference to variable of type ' . $type); + if (self::TYPE_REF !== $type) { + $this->fatalError($expr, 'Cannot assign reference to variable of type '.$type); } } if ($this->isVarExpr($expr->expr)) { - return $left . ' = ' . $this->parseIdentifier($expr->expr) . '.toReference()'; - } elseif ($expr->expr->getType() === self::EXPR_ARRAY_DIM_FETCH) { - return $left . ' = ' . $this->parseIdentifier($expr->expr); + return $left.' = '.$this->parseIdentifier($expr->expr).'.toReference()'; + } elseif (self::EXPR_ARRAY_DIM_FETCH === $expr->expr->getType()) { + return $left.' = '.$this->parseIdentifier($expr->expr); } elseif ($this->isPropertyFetch($expr->expr)) { $left = $this->parseIdentifier($expr->var); $object = $this->convertToObject($expr->expr->var); $prop = $this->identifierToStr($expr->expr->name); - return $left . ' = ' . $object . '.attrRef(' . $prop . ')'; + + return $left.' = '.$object.'.attrRef('.$prop.')'; } } abort($expr); @@ -2588,9 +2675,9 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseNativeMethodCall($object, $nativeFunc, $expr->args); } if (empty($expr->args)) { - return $object . '.exec("' . $method . '")'; + return $object.'.exec("'.$method.'")'; } else { - return $object . '.exec("' . $method . '", ' . $this->parseCallArgs($expr->args) . ')'; + return $object.'.exec("'.$method.'", '.$this->parseCallArgs($expr->args).')'; } } @@ -2601,19 +2688,21 @@ class CompilerBase extends \PhpAot\Core\Translator if ($require) { $this->requireVar($node, $id); } + return $id; } else { - if ($id === 'self') { + if ('self' === $id) { $id = $this->class; } - return '"'. $id . '"'; + + return '"'.$id.'"'; } } protected function requireVar($node, string $var): void { if (!$this->hasVar($var)) { - $this->fatalError($node, 'The variable `' . $var . '` is not defined'); + $this->fatalError($node, 'The variable `'.$var.'` is not defined'); } } @@ -2621,65 +2710,67 @@ class CompilerBase extends \PhpAot\Core\Translator { $method = $this->identifierToStr($expr->name); if (empty($expr->args)) { - return 'this_.callParentMethod(' . $method . ')'; + return 'this_.callParentMethod('.$method.')'; } else { - return 'this_.callParentMethod(' . $method . ', {' . $this->parseCallArgs($expr->args) . '})'; + return 'this_.callParentMethod('.$method.', {'.$this->parseCallArgs($expr->args).'})'; } } protected function parseStaticCall(Node\Expr\StaticCall $expr): string { if ($this->isVarExpr($expr->class) or $this->isVarExpr($expr->name)) { - $fn = 'php::concat({' . $this->identifierToStr($expr->class). ', "::", ' . $this->identifierToStr($expr->name) . '})'; + $fn = 'php::concat({'.$this->identifierToStr($expr->class).', "::", '.$this->identifierToStr($expr->name).'})'; } else { $class = $this->parseIdentifier($expr->class); - if ($class === 'self') { + if ('self' === $class) { $class = $this->class; - } elseif ($class === 'parent') { + } elseif ('parent' === $class) { return $this->parseParentMethodCall($expr); } $method = $this->parseIdentifier($expr->name); - $fn = '"' . $class . '::' . $method . '"'; + $fn = '"'.$class.'::'.$method.'"'; } if (empty($expr->args)) { - return 'php::call(' . $fn . ')'; + return 'php::call('.$fn.')'; } else { - return 'php::call(' . $fn . ', {' . $this->parseCallArgs($expr->args) . '})'; + return 'php::call('.$fn.', {'.$this->parseCallArgs($expr->args).'})'; } } protected function parseStaticPropertyFetch(Node $expr): string { - return 'php::getStaticProperty(' . $this->identifierToStr($expr->class) . ', ' . $this->identifierToStr($expr->name) . ')'; + return 'php::getStaticProperty('.$this->identifierToStr($expr->class).', '.$this->identifierToStr($expr->name).')'; } protected function parseClassConstFetch(Node\Expr\ClassConstFetch $expr): string { $class = $this->parseIdentifier($expr->class); - $class = ($class === 'self' or $class === 'this_') ? $this->class : $class; + $class = ('self' === $class or 'this_' === $class) ? $this->class : $class; $const = $this->parseIdentifier($expr->name); - return 'php::constant("' . $class . '::' . $const . '")'; + + return 'php::constant("'.$class.'::'.$const.'")'; } protected function parseThrow(mixed $expr): string { - if (!$this->isVarExpr($expr->expr) and $expr->expr->getType() != self::EXPR_NEW) { + if (!$this->isVarExpr($expr->expr) and self::EXPR_NEW != $expr->expr->getType()) { $this->fatalError($expr, 'The throw statement only accepts a object variable'); } - return 'php::throwException(' . $this->parseIdentifier($expr->expr). ')'; + + return 'php::throwException('.$this->parseIdentifier($expr->expr).')'; } protected function parseTryCatch(mixed $v): string { - $code = $this->parseBeforeStmtLines() . PHP_EOL; + $code = $this->parseBeforeStmtLines().PHP_EOL; $code .= 'try {'; $stmts = $v->stmts; $code .= PHP_EOL; - $this->indentLevel++; + ++$this->indentLevel; $code .= $this->parseStmts($stmts); - $this->indentLevel--; - $code .= $this->getIndent() . '}' . PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'}'.PHP_EOL; $catches = $v->catches; $finally = $v->finally; @@ -2687,21 +2778,22 @@ class CompilerBase extends \PhpAot\Core\Translator $exVar = $this->genTmpVarName(); $this->addLocalVar($exVar, self::TYPE_OBJECT); - $code .= 'catch(zend_object *_ex) {' . PHP_EOL; + $code .= 'catch(zend_object *_ex) {'.PHP_EOL; if ($catches) { - $code .= $this->getIndent() . $exVar . ' = php::catchException();' . PHP_EOL; - $this->indentLevel++; + $code .= $this->getIndent().$exVar.' = php::catchException();'.PHP_EOL; + ++$this->indentLevel; foreach ($catches as $catch) { $code .= $this->parseCatch($catch, $exVar); } - $this->indentLevel--; + --$this->indentLevel; } - $code .= '}' . PHP_EOL; + $code .= '}'.PHP_EOL; if ($finally) { $code .= $this->parseStmts($finally->stmts); $code .= PHP_EOL; } - $code .= 'if (' . $exVar . ') {' . PHP_EOL . $this->getIndent() . 'php::throwException(' . $exVar . ');' . PHP_EOL . $this->getIndent() . '}'; + $code .= 'if ('.$exVar.') {'.PHP_EOL.$this->getIndent().'php::throwException('.$exVar.');'.PHP_EOL.$this->getIndent().'}'; + return $code; } @@ -2712,40 +2804,42 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->hasVar($var)) { $this->addLocalVar($var, self::TYPE_OBJECT); } - $code = $this->getIndent() . $var . ' = ' . $exVar . ';' . PHP_EOL; + $code = $this->getIndent().$var.' = '.$exVar.';'.PHP_EOL; - $code .= $this->parseBeforeStmtLines() . PHP_EOL; + $code .= $this->parseBeforeStmtLines().PHP_EOL; - $code .= $this->getIndent() . 'if (' . $var . ' && '; + $code .= $this->getIndent().'if ('.$var.' && '; foreach ($types as $type) { - $code .= 'php::instanceOf(' . $var . ', "' . $this->parseIdentifier($type) . '")'; + $code .= 'php::instanceOf('.$var.', "'.$this->parseIdentifier($type).'")'; } - $code .= ') {' . PHP_EOL; - $this->indentLevel++; + $code .= ') {'.PHP_EOL; + ++$this->indentLevel; $code .= $this->parseStmts($catch->stmts); - $code .= $this->getIndent() . "$exVar.unset();" . PHP_EOL; - $this->indentLevel--; - $code .= $this->getIndent() . '}'; + $code .= $this->getIndent()."$exVar.unset();".PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'}'; return $code; } protected function parseShellExec(mixed $expr): string { - return 'php::call("shell_exec", {' . $this->parseInterpolatedString($expr) . '})'; + return 'php::call("shell_exec", {'.$this->parseInterpolatedString($expr).'})'; } protected function parseGoto(Node $v): string { $this->fatalError($v, 'Goto statement is not supported'); - return 'goto ' . $v->name->name . ';'; + + return 'goto '.$v->name->name.';'; } protected function parseLabel(Node $v): string { $this->fatalError($v, 'Label statement is not supported'); - return $v->name->name . ':'; + + return $v->name->name.':'; } protected function parseConstDef(mixed $v2): string @@ -2755,12 +2849,13 @@ class CompilerBase extends \PhpAot\Core\Translator $value = $this->parseIdentifier($const->value); $this->addConstant($name, $value); } + return ''; } protected function addConstant(string $name, string $value): void { - $constInfo = new stdClass(); + $constInfo = new \stdClass(); $constInfo->value = $value; $constInfo->type = $this->detectStrValueType($value); $this->nativeConstants[$name] = $constInfo; @@ -2792,12 +2887,13 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isBoolStr($constant)) { return self::TYPE_BOOL; } + return self::TYPE_VAR; } protected function isArrayVar($var): bool { - return $this->isVarExpr($var) and $this->hasVar($var->name) and $this->getVarType($var->name) == self::TYPE_ARRAY; + return $this->isVarExpr($var) and $this->hasVar($var->name) and self::TYPE_ARRAY == $this->getVarType($var->name); } protected function setBuildDir(string $string): void @@ -2814,30 +2910,24 @@ class CompilerBase extends \PhpAot\Core\Translator } /** - * @param string $file - * @return string * @throws \Exception */ protected function loadFile(string $file): string { if (!file_exists($file)) { - throw new \Exception('File not exists: ' . $file); + throw new \Exception('File not exists: '.$file); } $phpCode = file_get_contents($file); if (!$phpCode) { - throw new \Exception('Can not read file: ' . $file); + throw new \Exception('Can not read file: '.$file); } $this->file = realpath($file); $this->dir = dirname($this->file); $this->stubFile = $this->isStubFile($file); + return $phpCode; } - /** - * @param string $file - * @param string $content - * @return void - */ public function writeFile(string $file, string $content): void { $dir = dirname($file); @@ -2845,13 +2935,13 @@ class CompilerBase extends \PhpAot\Core\Translator mkdir($dir, 0777, true); } if (!file_put_contents($file, $content)) { - throw new RuntimeException('Can not write file: ' . $file); + throw new \RuntimeException('Can not write file: '.$file); } } public function getIncludeDir(): string { - return $this->getBuildDir() . '/include'; + return $this->getBuildDir().'/include'; } public function getBuildDir(): string @@ -2865,11 +2955,11 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($declares as $declare) { $key = $this->parseIdentifier($declare->key); $value = $this->parseIdentifier($declare->value); - if ($key === 'ticks') { + if ('ticks' === $key) { $this->fatalError($v, 'declare(ticks=1) is not supported'); - } elseif ($key === 'encoding') { - if (strtolower($value) !== 'utf-8') { - $this->fatalError($v, 'declare(encoding="' . $value . '") is not supported, only UTF-8 is supported'); + } elseif ('encoding' === $key) { + if ('utf-8' !== strtolower($value)) { + $this->fatalError($v, 'declare(encoding="'.$value.'") is not supported, only UTF-8 is supported'); } } $this->strictTypes = boolval(intval($value)); @@ -2881,12 +2971,12 @@ class CompilerBase extends \PhpAot\Core\Translator $code = ''; if ($this->useCppNamespace) { foreach ($v2->uses as $use) { - $code .= 'using ' . str_replace('\\', '::', $use->name->toString()) . ';' . PHP_EOL; + $code .= 'using '.str_replace('\\', '::', $use->name->toString()).';'.PHP_EOL; } } else { foreach ($v2->uses as $use) { $id = $this->parseIdentifier($use->name); - if ($use->type == Node\Stmt\Use_::TYPE_NORMAL) { + if (Node\Stmt\Use_::TYPE_NORMAL == $use->type) { $this->useNamespaces[] = $id; } else { $rpos = strrpos($id, '\\'); @@ -2897,6 +2987,7 @@ class CompilerBase extends \PhpAot\Core\Translator } } } + return $code; } @@ -2918,8 +3009,8 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->hasVar($name)) { $this->addLocalVar($name, self::TYPE_VAR); } else { - if ($this->getVarType($name) !== self::TYPE_VAR) { - $this->fatalError($node, 'Cannot assign value to variable of type ' . $this->getVarType($name)); + if (self::TYPE_VAR !== $this->getVarType($name)) { + $this->fatalError($node, 'Cannot assign value to variable of type '.$this->getVarType($name)); } } } @@ -2930,6 +3021,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($classDef->namespace === $this->namespace and $classDef->name == $this->class) { return true; } + // 类外部调用,只允许调用 public 方法 return $methodDef->flags & Modifiers::PUBLIC; } @@ -2937,7 +3029,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function findNativeMethod(NodeAbstract $expr, string $object, string $method): string|false { $nativeFunc = ''; - if ($object === 'this_') { + if ('this_' === $object) { $nativeFunc = $this->getNativeName($method, $this->namespace, $this->class); } elseif (isset($this->objects[$object])) { $class = $this->objects[$object]; @@ -2950,7 +3042,7 @@ class CompilerBase extends \PhpAot\Core\Translator } $methodDef = $classDef->methods[$method]; if (!$this->checkAccessible($classDef, $methodDef)) { - $this->fatalError($expr, 'Method `' . $classDef->getNamespacedName() . '::' . $method . '()` is not accessible'); + $this->fatalError($expr, 'Method `'.$classDef->getNamespacedName().'::'.$method.'()` is not accessible'); } $nativeFunc = $this->getNativeName($method, $classDef->namespace, $classDef->name); } @@ -2963,10 +3055,10 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseNativeMethodCall(string $object, string $nativeFunc, array $args): string { - if (count($args) === 0) { - return self::PREFIX . $nativeFunc . '(' . $object . ')'; + if (0 === count($args)) { + return self::PREFIX.$nativeFunc.'('.$object.')'; } else { - return self::PREFIX .$nativeFunc . '(' . $object . ', ' . $this->parseNativeCallArgs($args, $nativeFunc) . ')'; + return self::PREFIX.$nativeFunc.'('.$object.', '.$this->parseNativeCallArgs($args, $nativeFunc).')'; } } } diff --git a/src/Php/ConstantDef.php b/src/Php/ConstantDef.php index 6eba9732..231db6f6 100644 --- a/src/Php/ConstantDef.php +++ b/src/Php/ConstantDef.php @@ -16,4 +16,4 @@ class ConstantDef $this->flags = $flags; $this->value = $value; } -} \ No newline at end of file +} diff --git a/src/Php/Constants.php b/src/Php/Constants.php index fd787523..78b813af 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -4,7 +4,7 @@ namespace PhpAot\Php; class Constants { - const array CPP_RESERVED_NAMES = [ + public const array CPP_RESERVED_NAMES = [ 'auto', 'break', 'case', @@ -46,4 +46,4 @@ class Constants 'pipe', 'errno', // Linux error code ]; -} \ No newline at end of file +} diff --git a/src/Php/Encryptor.php b/src/Php/Encryptor.php index 9ca7241a..ba1aeaac 100644 --- a/src/Php/Encryptor.php +++ b/src/Php/Encryptor.php @@ -2,9 +2,6 @@ namespace PhpAot\Php; -use PhpParser\Node; -use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Identifier; use PhpParser\PrettyPrinter\Standard; class Encryptor extends \PhpAot\Core\Translator @@ -22,20 +19,21 @@ class Encryptor extends \PhpAot\Core\Translator public function __construct(array $stmts) { - $confDir = __DIR__ . '/../../config'; + $confDir = __DIR__.'/../../config'; $this->stmts = $stmts; - $this->encodeMap = require $confDir . '/functions.php'; + $this->encodeMap = require $confDir.'/functions.php'; $this->decodeMap = array_flip($this->encodeMap); - $this->constants = require $confDir . '/constants.php'; + $this->constants = require $confDir.'/constants.php'; } public function parseHeaders(): string { $lines = []; foreach ($this->headers as $header) { - $lines[] = '#include <' . $header . '>'; + $lines[] = '#include <'.$header.'>'; } - return implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; + + return implode(PHP_EOL, $lines).PHP_EOL.PHP_EOL; } public function setPhpxDir($dir): void @@ -47,6 +45,7 @@ class Encryptor extends \PhpAot\Core\Translator { $this->parseStmts($this->stmts); $prettyPrinter = new Standard(); + return $prettyPrinter->prettyPrintFile($this->stmts); } @@ -55,7 +54,6 @@ class Encryptor extends \PhpAot\Core\Translator file_put_contents($file, $code); } - public function getLine($node): int { return $node->getLine(); @@ -86,12 +84,12 @@ class Encryptor extends \PhpAot\Core\Translator $params = ''; } - $code = $return . ' ' . $name . '(' . $params . ') {' . PHP_EOL; - $this->indentLevel++; + $code = $return.' '.$name.'('.$params.') {'.PHP_EOL; + ++$this->indentLevel; $stmts = $this->parseStmts($v->stmts); - $this->indentLevel--; + --$this->indentLevel; $code .= $stmts; - $code .= "}"; + $code .= '}'; return $code; } @@ -107,7 +105,7 @@ class Encryptor extends \PhpAot\Core\Translator case 'Scalar_Float': return $node->value; case 'Scalar_String': - return '"' . $node->value . '"'; + return '"'.$node->value.'"'; case 'Expr_Array': return $this->parseArray($node); case 'Expr_FuncCall': @@ -129,16 +127,16 @@ class Encryptor extends \PhpAot\Core\Translator } } - private function parseParams($params) { $list = []; foreach ($params as $param) { $type = $param->type ? $this->parseType($param->type) : ''; $name = $param->var ? $this->parseIdentifier($param->var) : ''; - $list[] = $type . ' ' . $name; + $list[] = $type.' '.$name; $this->typeMap[$name] = $type; } + return implode(', ', $list); } @@ -152,10 +150,10 @@ class Encryptor extends \PhpAot\Core\Translator $lines[] = $this->parseFunctionDef($v); break; case 'Stmt_Expression': - $lines[] = $this->parseExpr($v->expr) . ';'; + $lines[] = $this->parseExpr($v->expr).';'; break; case 'Stmt_Echo': - $lines[] = $this->parseEcho($v) . ';'; + $lines[] = $this->parseEcho($v).';'; break; case 'Stmt_Return': $this->parseReturn($v); @@ -177,8 +175,9 @@ class Encryptor extends \PhpAot\Core\Translator } $code = ''; foreach ($lines as $line) { - $code .= $this->getIndent() . $line . PHP_EOL; + $code .= $this->getIndent().$line.PHP_EOL; } + return $code; } @@ -230,7 +229,7 @@ class Encryptor extends \PhpAot\Core\Translator private function parseEcho(mixed $v) { - return 'php::echo(' . $this->parseExprs($v->exprs) . ')'; + return 'php::echo('.$this->parseExprs($v->exprs).')'; } private function parseExprs($exprs) @@ -239,6 +238,7 @@ class Encryptor extends \PhpAot\Core\Translator foreach ($exprs as $expr) { $code .= $this->parseExpr($expr); } + return $code; } @@ -247,12 +247,12 @@ class Encryptor extends \PhpAot\Core\Translator $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return $left . ' + ' . $right; + return $left.' + '.$right; } private function parseReturn(mixed $v) { - return 'return ' . $this->parseExpr($v->expr); + return 'return '.$this->parseExpr($v->expr); } private function parseBinaryOpMul(mixed $expr) @@ -260,7 +260,7 @@ class Encryptor extends \PhpAot\Core\Translator $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return $left . ' * ' . $right; + return $left.' * '.$right; } private function detectType($var, $expr) @@ -284,18 +284,19 @@ class Encryptor extends \PhpAot\Core\Translator { $items = $node->items; $list = []; - $this->indentLevel++; + ++$this->indentLevel; foreach ($items as $item) { if ($item->key) { - $list[] = $this->getIndent() . '{ php::Variant(' . $this->parseIdentifier($item->key) . '), php::Variant(' . $this->parseIdentifier($item->value) . ') }'; + $list[] = $this->getIndent().'{ php::Variant('.$this->parseIdentifier($item->key).'), php::Variant('.$this->parseIdentifier($item->value).') }'; } else { - $list[] = $this->getIndent() . 'php::Variant(' . $this->parseIdentifier($item->value) . ')'; + $list[] = $this->getIndent().'php::Variant('.$this->parseIdentifier($item->value).')'; } } - $this->indentLevel--; - return '{' . PHP_EOL . - implode(', ' . PHP_EOL, $list) . PHP_EOL . - $this->getIndent() . + --$this->indentLevel; + + return '{'.PHP_EOL. + implode(', '.PHP_EOL, $list).PHP_EOL. + $this->getIndent(). '}'; } @@ -317,12 +318,13 @@ class Encryptor extends \PhpAot\Core\Translator private function parseIncludes() { $list = [ - $this->phpxDir . '/include', + $this->phpxDir.'/include', ]; $out = '$(php-config --includes) '; foreach ($list as $li) { - $out .= '-I ' . $li . ' '; + $out .= '-I '.$li.' '; } + return $out; } @@ -330,12 +332,13 @@ class Encryptor extends \PhpAot\Core\Translator { $list = [ '$(php-config --prefix)/lib', - $this->phpxDir . '/lib', + $this->phpxDir.'/lib', ]; $out = ''; foreach ($list as $li) { - $out .= '-L ' . $li . ' '; + $out .= '-L '.$li.' '; } + return $out; } @@ -347,15 +350,16 @@ class Encryptor extends \PhpAot\Core\Translator ]; $out = ''; foreach ($list as $li) { - $out .= '-l' . $li . ' '; + $out .= '-l'.$li.' '; } + return $out; } public function compileFile($file) { - $cmd = 'g++ -c ' . $file . ' -o ' . $file . '.o ' . $this->parseIncludes() . $this->parseLdflags() . $this->parseLibs(); - echo $cmd . PHP_EOL; + $cmd = 'g++ -c '.$file.' -o '.$file.'.o '.$this->parseIncludes().$this->parseLdflags().$this->parseLibs(); + echo $cmd.PHP_EOL; shell_exec($cmd); } @@ -364,7 +368,7 @@ class Encryptor extends \PhpAot\Core\Translator $left = $this->parseIdentifier($expr->left); $right = $this->parseIdentifier($expr->right); - return $left . ' + ' . $right; + return $left.' + '.$right; } private function parseFuncCall($expr) @@ -372,6 +376,7 @@ class Encryptor extends \PhpAot\Core\Translator if (isset($this->decodeMap[$expr->name])) { $expr->name = $this->decodeMap[$expr->name]; } + return $expr; } @@ -425,7 +430,6 @@ class Encryptor extends \PhpAot\Core\Translator { $name = $expr->name->name; if (isset($this->constants[$name])) { - } } } diff --git a/src/Php/Extractor.php b/src/Php/Extractor.php index 401771fe..0ca68f19 100644 --- a/src/Php/Extractor.php +++ b/src/Php/Extractor.php @@ -13,28 +13,29 @@ class Extractor } /** - * 检查 ctags 是否可用 + * 检查 ctags 是否可用. */ private function checkCtags(): void { $output = shell_exec("{$this->ctagsPath} --version 2>&1"); - if ($output === null) { + if (null === $output) { $this->error("未找到 ctags 命令\n安装: sudo apt install universal-ctags"); } - $this->isUniversalCtags = stripos($output, 'Universal Ctags') !== false; + $this->isUniversalCtags = false !== stripos($output, 'Universal Ctags'); if (!$this->isUniversalCtags) { - $this->warn("建议使用 Universal Ctags 以获得更好的支持"); + $this->warn('建议使用 Universal Ctags 以获得更好的支持'); } } /** - * 提取函数定义 + * 提取函数定义. * * @param string $filename 文件路径 - * @param array $prefixes 函数名前缀列表 + * @param array $prefixes 函数名前缀列表 + * * @return array 函数列表 */ public function extractFunctions(string $filename, array $prefixes = ['php_']): array @@ -44,7 +45,7 @@ class Extractor } $this->info("分析文件: {$filename}"); - $this->info("函数前缀: " . implode(', ', $prefixes)); + $this->info('函数前缀: '.implode(', ', $prefixes)); // 运行 ctags $tags = $this->runCtags($filename); @@ -52,7 +53,7 @@ class Extractor // 过滤和解析函数 $functions = []; foreach ($tags as $tag) { - if ($tag['kind'] !== 'function') { + if ('function' !== $tag['kind']) { continue; } @@ -78,13 +79,13 @@ class Extractor } } - $this->info("找到 " . count($functions) . " 个函数"); + $this->info('找到 '.count($functions).' 个函数'); return $functions; } /** - * 运行 ctags 命令 + * 运行 ctags 命令. */ private function runCtags(string $filename): array { @@ -96,8 +97,8 @@ class Extractor $output = shell_exec($cmd); - if ($output === null) { - throw new RuntimeException("ctags 执行失败"); + if (null === $output) { + throw new RuntimeException('ctags 执行失败'); } // 解析 JSON 输出 @@ -110,7 +111,7 @@ class Extractor } $tag = json_decode($line, true); - if ($tag === null) { + if (null === $tag) { continue; } @@ -121,7 +122,7 @@ class Extractor } /** - * 解析单个函数的详细信息 + * 解析单个函数的详细信息. */ private function parseFunction(string $filename, array $tag): ?array { @@ -152,21 +153,21 @@ class Extractor 'parameters' => $parameters, 'location' => [ 'file' => $filename, - 'line' => $lineNum + 'line' => $lineNum, ], 'scope' => $tag['scope'] ?? null, - 'scopeKind' => $tag['scopeKind'] ?? null + 'scopeKind' => $tag['scopeKind'] ?? null, ]; } /** - * 从源文件中提取完整的函数签名 + * 从源文件中提取完整的函数签名. */ private function extractSignature(string $filename, int $lineNum, string $funcName): string { $lines = file($filename, FILE_IGNORE_NEW_LINES); - if ($lines === false || $lineNum > count($lines)) { + if (false === $lines || $lineNum > count($lines)) { return ''; } @@ -174,12 +175,12 @@ class Extractor $signatureLines = []; $maxLines = min($lineNum + 20, count($lines)); - for ($i = $lineNum - 1; $i < $maxLines; $i++) { + for ($i = $lineNum - 1; $i < $maxLines; ++$i) { $line = $lines[$i]; $signatureLines[] = $line; // 检查是否到达函数体或声明结束 - if (strpos($line, '{') !== false || strpos($line, ';') !== false) { + if (false !== strpos($line, '{') || false !== strpos($line, ';')) { break; } } @@ -200,12 +201,12 @@ class Extractor } /** - * 解析返回类型 + * 解析返回类型. */ private function parseReturnType(string $signature, string $funcName): string { // 匹配: <返回类型> <函数名>( - $pattern = '/^(.+?)\s+' . preg_quote($funcName, '/') . '\s*\(/'; + $pattern = '/^(.+?)\s+'.preg_quote($funcName, '/').'\s*\(/'; if (preg_match($pattern, $signature, $matches)) { $returnType = trim($matches[1]); @@ -222,12 +223,12 @@ class Extractor } /** - * 解析参数列表 + * 解析参数列表. */ private function parseParameters(string $signature, string $funcName): array { // 提取括号内的参数 - $pattern = '/' . preg_quote($funcName, '/') . '\s*\((.*?)\)/s'; + $pattern = '/'.preg_quote($funcName, '/').'\s*\((.*?)\)/s'; if (!preg_match($pattern, $signature, $matches)) { return []; @@ -236,7 +237,7 @@ class Extractor $paramsStr = trim($matches[1]); // 空参数或 void - if (empty($paramsStr) || $paramsStr === 'void') { + if (empty($paramsStr) || 'void' === $paramsStr) { return []; } @@ -261,7 +262,7 @@ class Extractor } /** - * 智能分割参数(处理嵌套的模板和括号) + * 智能分割参数(处理嵌套的模板和括号). */ private function splitParameters(string $paramsStr): array { @@ -270,16 +271,16 @@ class Extractor $depth = 0; $length = strlen($paramsStr); - for ($i = 0; $i < $length; $i++) { + for ($i = 0; $i < $length; ++$i) { $char = $paramsStr[$i]; - if ($char === '<' || $char === '(' || $char === '[') { - $depth++; + if ('<' === $char || '(' === $char || '[' === $char) { + ++$depth; $current .= $char; - } elseif ($char === '>' || $char === ')' || $char === ']') { - $depth--; + } elseif ('>' === $char || ')' === $char || ']' === $char) { + --$depth; $current .= $char; - } elseif ($char === ',' && $depth === 0) { + } elseif (',' === $char && 0 === $depth) { $params[] = $current; $current = ''; } else { @@ -295,7 +296,7 @@ class Extractor } /** - * 解析单个参数 + * 解析单个参数. */ private function parseParameter(string $param): ?array { @@ -309,19 +310,19 @@ class Extractor if (preg_match('/^(.+?)\s+(\w+)\s*$/', $param, $matches)) { return [ 'type' => trim($matches[1]), - 'name' => trim($matches[2]) + 'name' => trim($matches[2]), ]; } // 只有类型,没有名称 return [ 'type' => $param, - 'name' => '' + 'name' => '', ]; } /** - * 批量提取多个文件 + * 批量提取多个文件. */ public function extractFromFiles(array $files, array $prefixes = ['php_']): array { @@ -332,7 +333,7 @@ class Extractor $functions = $this->extractFunctions($file, $prefixes); $allFunctions = array_merge($allFunctions, $functions); } catch (Exception $e) { - $this->error("处理文件 {$file} 失败: " . $e->getMessage()); + $this->error("处理文件 {$file} 失败: ".$e->getMessage()); } } @@ -340,7 +341,7 @@ class Extractor } /** - * 输出信息 + * 输出信息. */ private function info(string $message): void { @@ -348,7 +349,7 @@ class Extractor } /** - * 输出警告 + * 输出警告. */ private function warn(string $message): void { @@ -356,7 +357,7 @@ class Extractor } /** - * 输出错误并退出 + * 输出错误并退出. */ private function error(string $message): void { @@ -365,7 +366,7 @@ class Extractor } /** - * 提取函数并添加额外信息 + * 提取函数并添加额外信息. */ public function extractWithMetadata(string $filename, array $prefixes = ['php_']): array { @@ -380,7 +381,7 @@ class Extractor } /** - * 提取函数的元数据(注释、属性等) + * 提取函数的元数据(注释、属性等). */ private function extractMetadata(string $filename, array $func): array { @@ -404,8 +405,8 @@ class Extractor // 检测修饰符 $signature = $func['signature']; - $metadata['isStatic'] = strpos($signature, 'static') !== false; - $metadata['isInline'] = strpos($signature, 'inline') !== false; + $metadata['isStatic'] = false !== strpos($signature, 'static'); + $metadata['isInline'] = false !== strpos($signature, 'inline'); // 提取文档注释中的标签 $metadata['docTags'] = $this->parseDocTags($comments); @@ -414,7 +415,7 @@ class Extractor } /** - * 提取函数前的注释 + * 提取函数前的注释. */ private function extractComments(array $lines, int $lineNum): array { @@ -427,21 +428,21 @@ class Extractor // 空行 if (empty($line)) { - $i--; + --$i; continue; } // C++ 风格注释 if (str_starts_with($line, '//')) { array_unshift($comments, substr($line, 2)); - $i--; + --$i; continue; } // C 风格注释结束 if (str_ends_with($line, '*/')) { $commentLines = [$line]; - $i--; + --$i; // 继续向上查找注释开始 while ($i >= 0) { @@ -451,7 +452,7 @@ class Extractor if (str_starts_with($commentLine, '/*')) { break; } - $i--; + --$i; } // 解析多行注释 @@ -461,7 +462,7 @@ class Extractor $comment = preg_replace('#^\s*\*\s?#m', '', $comment); array_unshift($comments, trim($comment)); - $i--; + --$i; continue; } @@ -473,7 +474,7 @@ class Extractor } /** - * 检测是否是 PHP 函数宏定义 + * 检测是否是 PHP 函数宏定义. */ private function isPHPFunction(string $signature): bool { @@ -485,7 +486,7 @@ class Extractor ]; foreach ($phpMacros as $macro) { - if (strpos($signature, $macro) !== false) { + if (false !== strpos($signature, $macro)) { return true; } } @@ -494,7 +495,7 @@ class Extractor } /** - * 解析文档注释标签 + * 解析文档注释标签. */ private function parseDocTags(array $comments): array { @@ -520,7 +521,7 @@ class Extractor } /** - * 生成函数统计信息 + * 生成函数统计信息. */ public function generateStatistics(array $functions): array { @@ -552,12 +553,12 @@ class Extractor // 有注释的函数 if (!empty($func['metadata']['comments'])) { - $stats['withComments']++; + ++$stats['withComments']; } // PHP 函数宏 if ($func['metadata']['isPHPFunction'] ?? false) { - $stats['isPHPFunction']++; + ++$stats['isPHPFunction']; } } @@ -565,13 +566,13 @@ class Extractor } /** - * 导出为 Markdown 文档 + * 导出为 Markdown 文档. */ public function exportToMarkdown(array $functions, string $title = 'API 文档'): string { $md = "# {$title}\n\n"; - $md .= "生成时间: " . date('Y-m-d H:i:s') . "\n\n"; - $md .= "总计: " . count($functions) . " 个函数\n\n"; + $md .= '生成时间: '.date('Y-m-d H:i:s')."\n\n"; + $md .= '总计: '.count($functions)." 个函数\n\n"; $md .= "---\n\n"; foreach ($functions as $func) { @@ -599,7 +600,7 @@ class Extractor if (!empty($func['metadata']['comments'])) { $md .= "**说明**:\n\n"; foreach ($func['metadata']['comments'] as $comment) { - $md .= $comment . "\n\n"; + $md .= $comment."\n\n"; } } diff --git a/src/Php/FileScanner.php b/src/Php/FileScanner.php index 30e9f822..4343273a 100644 --- a/src/Php/FileScanner.php +++ b/src/Php/FileScanner.php @@ -2,8 +2,6 @@ namespace PhpAot\Php; -use FilesystemIterator; - class FileScanner { private string $directory; @@ -45,12 +43,14 @@ class FileScanner public function addExcludePattern(string $pattern): self { $this->excludePatterns[] = $pattern; + return $this; } public function setExcludePatterns(array $patterns): self { $this->excludePatterns = $patterns; + return $this; } @@ -68,6 +68,7 @@ class FileScanner break; } } + return $excluded; } @@ -75,7 +76,7 @@ class FileScanner { $files = []; $iterator = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS) + new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS) ); foreach ($iterator as $file) { @@ -92,6 +93,7 @@ class FileScanner } } } + return $files; } diff --git a/src/Php/FileSorter.php b/src/Php/FileSorter.php index 91fd27db..0b6c87c9 100644 --- a/src/Php/FileSorter.php +++ b/src/Php/FileSorter.php @@ -22,13 +22,13 @@ class FileSorter $inDegree = array_fill_keys($allFiles, 0); foreach ($dependencies as $deps) { foreach ($deps as $dep) { - $inDegree[$dep]++; + ++$inDegree[$dep]; } } $queue = []; foreach ($inDegree as $file => $degree) { - if ($degree === 0) { + if (0 === $degree) { $queue[] = $file; } } @@ -40,8 +40,8 @@ class FileSorter if (isset($dependencies[$current])) { foreach ($dependencies[$current] as $dep) { - $inDegree[$dep]--; - if ($inDegree[$dep] === 0) { + --$inDegree[$dep]; + if (0 === $inDegree[$dep]) { $queue[] = $dep; } } @@ -49,7 +49,7 @@ class FileSorter } if (count($sorted) !== count($allFiles)) { - throw new \RuntimeException("Circular dependency of function call detected"); + throw new \RuntimeException('Circular dependency of function call detected'); } return array_reverse($sorted); diff --git a/src/Php/FuncCallOptimizer.php b/src/Php/FuncCallOptimizer.php index 5c7a37ca..24a227c5 100644 --- a/src/Php/FuncCallOptimizer.php +++ b/src/Php/FuncCallOptimizer.php @@ -8,10 +8,10 @@ trait FuncCallOptimizer { protected function parseFuncCallWithOptimizer(string $name, Node\Expr\FuncCall $expr): string|false { - if ($name === 'strlen' or $name === 'sizeof' or $name === 'count') { - return 'php::len(' . $this->parseIdentifier($expr->args[0]->value) . ')'; + if ('strlen' === $name or 'sizeof' === $name or 'count' === $name) { + return 'php::len('.$this->parseIdentifier($expr->args[0]->value).')'; } - if (count($expr->args) == 1) { + if (1 == count($expr->args)) { switch ($name) { case 'intval': return $this->convertIntExpr($this->parseExpr($expr->args[0]->value)); @@ -24,19 +24,21 @@ trait FuncCallOptimizer default: break; } - } elseif (count($expr->args) == 2) { + } elseif (2 == count($expr->args)) { switch ($name) { case 'objval': $arg1 = $expr->args[0]->value; $arg2 = $expr->args[1]->value; + return $this->convertObjectExpr($this->parseExpr($arg1), $this->parseExpr($arg2)); default: break; } } - if ($name === 'abs') { - return 'php::math::abs(' . $this->parseIdentifier($expr->args[0]->value) . ')'; + if ('abs' === $name) { + return 'php::math::abs('.$this->parseIdentifier($expr->args[0]->value).')'; } + return false; } -} \ No newline at end of file +} diff --git a/src/Php/FunctionDef.php b/src/Php/FunctionDef.php index a36ee74c..56f04c39 100644 --- a/src/Php/FunctionDef.php +++ b/src/Php/FunctionDef.php @@ -14,7 +14,6 @@ class FunctionDef public string $params = ''; public bool $method = false; - public function __construct(string $name, string $returnType) { $this->name = $name; diff --git a/src/Php/InterfaceDef.php b/src/Php/InterfaceDef.php index aa6a742b..058ee176 100644 --- a/src/Php/InterfaceDef.php +++ b/src/Php/InterfaceDef.php @@ -8,4 +8,4 @@ class InterfaceDef extends ClassLikeDef { parent::__construct($name, $namespace); } -} \ No newline at end of file +} diff --git a/src/Php/MagicMethodDetector.php b/src/Php/MagicMethodDetector.php index f431377c..4170c0ef 100644 --- a/src/Php/MagicMethodDetector.php +++ b/src/Php/MagicMethodDetector.php @@ -6,16 +6,16 @@ use PhpParser\NodeAbstract; trait MagicMethodDetector { - function checkRequiredArgNum(string $name, MethodDef $methodDef, NodeAbstract $v): void + public function checkRequiredArgNum(string $name, MethodDef $methodDef, NodeAbstract $v): void { - if ($name == '__call' or $name == '__callStatic' or $name == '__set') { - if (count($methodDef->functionDef->argInfoList) != 2) { - $this->fatalError($v, 'Method ' . $this->class . "::$name() must take exactly 2 arguments"); + if ('__call' == $name or '__callStatic' == $name or '__set' == $name) { + if (2 != count($methodDef->functionDef->argInfoList)) { + $this->fatalError($v, 'Method '.$this->class."::$name() must take exactly 2 arguments"); } - } elseif ($name == '__get') { - if (count($methodDef->functionDef->argInfoList) != 1) { - $this->fatalError($v, 'Method ' . $this->class . "::$name() must take exactly 1 argument"); + } elseif ('__get' == $name) { + if (1 != count($methodDef->functionDef->argInfoList)) { + $this->fatalError($v, 'Method '.$this->class."::$name() must take exactly 1 argument"); } } } -} \ No newline at end of file +} diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 71218e95..cef6797e 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -39,7 +39,7 @@ class Preprocessor extends CompilerBase $this->prepareClass($v2); break; case 'Stmt_Function': - $this->prepareFunction($v2) . PHP_EOL; + $this->prepareFunction($v2).PHP_EOL; break; case 'Stmt_Use': case 'Stmt_Const': @@ -54,13 +54,15 @@ class Preprocessor extends CompilerBase public function getCppFile(string $file): string { $info = pathinfo($file); - return $this->buildDir . '/' . $this->removeCommonPrefix($this->buildDir, $info['dirname'] . '/' . $info['filename'] . '.cc'); + + return $this->buildDir.'/'.$this->removeCommonPrefix($this->buildDir, $info['dirname'].'/'.$info['filename'].'.cc'); } public function getObjectFile(string $cppFile): string { $info = pathinfo($cppFile); - return $info['dirname'] . '/' . $info['filename'] . '.o'; + + return $info['dirname'].'/'.$info['filename'].'.o'; } public function hasCppFileCache(string $file): bool @@ -72,19 +74,21 @@ class Preprocessor extends CompilerBase if (file_exists($cppFile) and filemtime($cppFile) > filemtime($file)) { return true; } + return false; } public function prepare(string $file): void { if ($this->hasCppFileCache($file)) { - $this->climate->darkGray('skip: ' . $file . ', cache exists'); + $this->climate->darkGray('skip: '.$file.', cache exists'); + return; } $phpCode = $this->loadFile($file); - $this->climate->info('prepare: ' . $this->file); + $this->climate->info('prepare: '.$this->file); try { $ast = $this->parser->parse($phpCode); } catch (\PhpParser\Error $e) { @@ -107,7 +111,7 @@ class Preprocessor extends CompilerBase $this->prepareClass($v); break; case 'Stmt_Function': - $this->prepareFunction($v) . PHP_EOL; + $this->prepareFunction($v).PHP_EOL; break; case 'Stmt_Declare': case 'Stmt_Use': @@ -116,7 +120,7 @@ class Preprocessor extends CompilerBase case 'Stmt_Nop': break; default: - $this->fatalError($v, 'Unsupported statement: ' . $type); + $this->fatalError($v, 'Unsupported statement: '.$type); break; } } @@ -146,7 +150,6 @@ class Preprocessor extends CompilerBase } } - protected function prepareClass(Node\Stmt\Class_|Node\Stmt\Trait_ $class): string { $this->class = $this->parseIdentifier($class->name); @@ -160,13 +163,14 @@ class Preprocessor extends CompilerBase case 'Stmt_TraitUse': break; case 'Stmt_ClassMethod': - $code .= $this->prepareFunction($v) . PHP_EOL; + $code .= $this->prepareFunction($v).PHP_EOL; break; default: abort($v); } } $this->class = ''; + return $code; } -} \ No newline at end of file +} diff --git a/src/Php/PropertyDef.php b/src/Php/PropertyDef.php index 6f0f1d0c..56f9bd3f 100644 --- a/src/Php/PropertyDef.php +++ b/src/Php/PropertyDef.php @@ -9,7 +9,7 @@ class PropertyDef public string $name; public string $type; public int $flags; - public ?string $default = null; + public ?string $default = null; public function __construct(string $name, int $flags, string $type, ?string $default = null) { @@ -33,4 +33,4 @@ class PropertyDef { return !$this->isPrivate() && !$this->isProtected(); } -} \ No newline at end of file +} diff --git a/src/Php/Reflection.php b/src/Php/Reflection.php index 33bacb9e..8cda6518 100644 --- a/src/Php/Reflection.php +++ b/src/Php/Reflection.php @@ -2,10 +2,6 @@ namespace PhpAot\Php; -use ReflectionFunction; -use ReflectionParameter; -use ReflectionUnionType; - class Reflection { private static array $functions = []; @@ -14,13 +10,13 @@ class Reflection { if (!isset(self::$functions[$fn])) { try { - $ref = new ReflectionFunction($fn); - ; + $ref = new \ReflectionFunction($fn); } catch (\ReflectionException $e) { return null; } self::$functions[$fn] = $ref; } + return self::$functions[$fn]; } @@ -34,13 +30,14 @@ class Reflection if (!$returnType) { return null; } - if ($returnType instanceof ReflectionUnionType) { + if ($returnType instanceof \ReflectionUnionType) { return null; } + return $returnType->getName(); } - public static function getFunctionParameter(string $fn, int $index): ?ReflectionParameter + public static function getFunctionParameter(string $fn, int $index): ?\ReflectionParameter { $func = self::getFunction($fn); if (!$func) { @@ -50,6 +47,7 @@ class Reflection if ($index >= count($args)) { return null; } + return $args[$index]; } @@ -59,6 +57,7 @@ class Reflection if (!$param) { return null; } + return $param->isPassedByReference() ? $param->getName() : null; } } diff --git a/src/Php/SyntaxError.php b/src/Php/SyntaxError.php index 689a8cb6..21364bfb 100644 --- a/src/Php/SyntaxError.php +++ b/src/Php/SyntaxError.php @@ -4,5 +4,4 @@ namespace PhpAot\Php; class SyntaxError extends \RuntimeException { - -} \ No newline at end of file +} diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 3624d30b..89455b8c 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -3,12 +3,11 @@ namespace PhpAot\Php; use MJS\TopSort\Implementations\StringSort; -use Symfony\Component\Yaml\Yaml; use PhpParser\Modifiers; use PhpParser\Node; use PhpParser\Node\Stmt\Foreach_; -use PhpParser\NodeAbstract; use PhpParser\NodeTraverser; +use Symfony\Component\Yaml\Yaml; class Translator extends Preprocessor { @@ -30,14 +29,14 @@ class Translator extends Preprocessor public function __construct(string $rootPath) { parent::__construct($rootPath); - $this->climate->arguments->add(require __DIR__ . '/../config/compiler_options.php'); + $this->climate->arguments->add(require __DIR__.'/../config/compiler_options.php'); $this->preprocessArgvAdvanced(); $this->climate->arguments->parse(); $this->optimizeLevel = $this->climate->arguments->get('optimize'); $this->buildMode = $this->climate->arguments->get('mode'); $this->debugLine = intval($this->climate->arguments->get('debug-line')); -// $this->noLiteralStrings = $this->climate->arguments->get('noLiteralStrings'); + // $this->noLiteralStrings = $this->climate->arguments->get('noLiteralStrings'); $this->noLiteralStrings = true; $this->enableProfiler = $this->climate->arguments->defined('profile'); $this->internalFunctions = array_flip(get_defined_functions()['internal']); @@ -84,7 +83,8 @@ class Translator extends Preprocessor public function convert(string $file): string { if ($this->hasCppFileCache($file)) { - $this->climate->darkGray('skip: ' . $file . ', cache exists'); + $this->climate->darkGray('skip: '.$file.', cache exists'); + return $this->getCppFile($file); } $phpCode = $this->loadFile($file); @@ -96,6 +96,7 @@ class Translator extends Preprocessor $cppFile = $this->getCppFile($file); $this->save($cppCode, $cppFile); $this->phpSrcFiles[] = $file; + return $cppFile; } catch (RedoException $e) { continue; @@ -105,14 +106,14 @@ class Translator extends Preprocessor protected function getRegisterClassFunction(string $name): string { - return self::PREFIX . 'register_class_' . $name; + return self::PREFIX.'register_class_'.$name; } protected function getRegisterClassFunctionCeList(ClassDef|InterfaceDef $classDef): array { $list = []; $parentCe = $this->getParentClassCe($classDef); - if ($parentCe !== '') { + if ('' !== $parentCe) { $list = [$parentCe]; } // interface 没有 implements @@ -120,6 +121,7 @@ class Translator extends Preprocessor return $list; } $implements = $this->getImplementCe($classDef); + return array_merge($list, $implements); } @@ -134,12 +136,13 @@ class Translator extends Preprocessor if (empty($depsCeList)) { return ''; } - return 'zend_class_entry *' . implode(', zend_class_entry *', $depsCeList); + + return 'zend_class_entry *'.implode(', zend_class_entry *', $depsCeList); } protected function getClassCe(ClassLikeDef $classDef): string { - return self::PREFIX . 'class_entry_' . $classDef->getNamespacedName(); + return self::PREFIX.'class_entry_'.$classDef->getNamespacedName(); } public function setTargetName(string $name): void @@ -162,6 +165,7 @@ class Translator extends Preprocessor protected function getFilesFromDir(string $path): array { $scanner = new FileScanner($path); + return $scanner->scan(); } @@ -175,14 +179,14 @@ class Translator extends Preprocessor $list = []; foreach ($sources as $src) { $src = trim($src); - if ($src[0] != '/') { - $absPath = $projectDir . '/' . $src; + if ('/' != $src[0]) { + $absPath = $projectDir.'/'.$src; } else { $absPath = $src; } $realPath = realpath($absPath); if (!$realPath) { - $this->error('Source file not exists: `' . $src . '`'); + $this->error('Source file not exists: `'.$src.'`'); } if (is_file($realPath)) { $list[] = $realPath; @@ -198,27 +202,28 @@ class Translator extends Preprocessor if (is_array($cfg['cxxflags'])) { $this->cxxflags = implode(' ', $cfg['cxxflags']); } else { - $this->cxxflags = str_replace("\n", " ", $cfg['cxxflags']); + $this->cxxflags = str_replace("\n", ' ', $cfg['cxxflags']); } } if (!empty($cfg['ldflags'])) { if (is_array($cfg['ldflags'])) { $this->ldflags = implode(' ', $cfg['ldflags']); } else { - $this->ldflags = str_replace("\n", " ", $cfg['ldflags']); + $this->ldflags = str_replace("\n", ' ', $cfg['ldflags']); } } if (!empty($cfg['name'])) { $this->setTargetName($cfg['name']); } + return $list; } public function getFiles(string $path): array { $realpath = realpath($path); - if ($realpath === false) { - die("path not exists: $path\n"); + if (false === $realpath) { + exit("path not exists: $path\n"); } $path = $realpath; @@ -228,16 +233,17 @@ class Translator extends Preprocessor $this->setTargetName($targetName); } else { $ext = pathinfo($path, PATHINFO_EXTENSION); - if ($ext === 'yml') { + if ('yml' === $ext) { $list = $this->parseProjectYaml($path); - } elseif ($ext === 'php') { + } elseif ('php' === $ext) { $list = [$path]; $targetName = FileScanner::getFileName($path); $this->setTargetName($targetName); } else { - $this->error('Unsupported file type: ' . $path); + $this->error('Unsupported file type: '.$path); } } + return $list; } @@ -245,7 +251,7 @@ class Translator extends Preprocessor { return [ 'func' => 'php::getClassEntry', - 'args' => '"' . substr($ce, strlen(self::PREFIX . 'class_entry_')) . '"', + 'args' => '"'.substr($ce, strlen(self::PREFIX.'class_entry_')).'"', ]; } @@ -254,21 +260,23 @@ class Translator extends Preprocessor if (!$classDef->extends) { return ''; } - return self::PREFIX . 'class_entry_' . $classDef->extends; + + return self::PREFIX.'class_entry_'.$classDef->extends; } private function getImplementCe(ClassDef $classDef): array { $list = []; foreach ($classDef->implements as $interface) { - $list[] = self::PREFIX . 'class_entry_' . $interface; + $list[] = self::PREFIX.'class_entry_'.$interface; } + return $list; } protected function doConvert(string $phpCode): string { - $this->climate->info('convert: ' . $this->file); + $this->climate->info('convert: '.$this->file); $ast = $this->parser->parse($phpCode); $traverser = new NodeTraverser(); @@ -296,16 +304,16 @@ class Translator extends Preprocessor $cppCode .= $this->parseClass($v); break; case 'Stmt_Use': - $cppCode .= $this->parseUse($v) . PHP_EOL; + $cppCode .= $this->parseUse($v).PHP_EOL; break; case 'Stmt_Function': - $cppCode .= $this->parseFunction($v) . PHP_EOL; + $cppCode .= $this->parseFunction($v).PHP_EOL; break; case 'Stmt_Const': - $this->parseConstDef($v) . PHP_EOL; + $this->parseConstDef($v).PHP_EOL; break; case 'Stmt_Interface': - $this->parseInterface($v) . PHP_EOL; + $this->parseInterface($v).PHP_EOL; break; case 'Stmt_Nop': break; @@ -326,7 +334,7 @@ class Translator extends Preprocessor $cppCode .= $this->genFunctionWrapper($functionDef); } - return $this->genIncludeHeaderFiles() . $cppCode; + return $this->genIncludeHeaderFiles().$cppCode; } public function preprocessArgvAdvanced(): void @@ -334,7 +342,7 @@ class Translator extends Preprocessor global $argv; $processed = [$argv[0]]; - for ($i = 1; $i < count($argv); $i++) { + for ($i = 1; $i < count($argv); ++$i) { $arg = $argv[$i]; if (preg_match('/^-([a-zA-Z])(.+)$/', $arg, $matches)) { $option = $matches[1]; @@ -358,26 +366,31 @@ class Translator extends Preprocessor $lines[] = '#include '; $lines[] = PHP_EOL; foreach ($this->globalVars as $name => $type) { - $lines[] = 'extern ' . self::TYPE_VAR . ' ' . $name . ';'; + $lines[] = 'extern '.self::TYPE_VAR.' '.$name.';'; } // property offset foreach ($this->classes as $classDef) { foreach ($classDef->properties as $propertyDef) { - $lines[] = 'extern uint32_t ' . self::PREFIX . $this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace) . ';'; + $lines[] = 'extern uint32_t '.self::PREFIX.$this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace).';'; } } $literalStringsCount = count($this->literalStrings); - $lines[] = 'extern php::Var ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; - $code = implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; + $lines[] = 'extern php::Var '.self::LITERAL_STRINGS.'['.$literalStringsCount.'];'.PHP_EOL; + + $classEntryCount = count($this->classMap); + $lines[] = 'extern zend_class_entry *'.self::PREFIX.self::CLASS_ENTRY_MAP.'['.$classEntryCount.'];'.PHP_EOL; + + $code = implode(PHP_EOL, $lines).PHP_EOL.PHP_EOL; $this->writeFile($file, $code); } private function render(string $template): string { ob_start(); - include __DIR__ . '/../template/' . $template; + include __DIR__.'/../template/'.$template; + return ob_get_clean(); } @@ -428,7 +441,7 @@ class Translator extends Preprocessor $implements = $classDef->implements; if ($implements) { foreach ($implements as $interface) { - $tmpCe = self::PREFIX . 'class_entry_' . $interface; + $tmpCe = self::PREFIX.'class_entry_'.$interface; if (!isset($this->interfaces[$interface])) { $sorter->add($tmpCe); } @@ -450,7 +463,7 @@ class Translator extends Preprocessor public function genExtension(string $file): void { - if ($this->buildMode == 'bin') { + if ('bin' == $this->buildMode) { if (!isset($this->nativeFunctions['main'])) { $this->climate->red('When the build mode is a binary executable file, the `main()` function must be defined'); exit(1); @@ -473,16 +486,18 @@ class Translator extends Preprocessor if (file_exists($objectFile) and filemtime($objectFile) > filemtime($cppFile)) { return true; } + return false; } public function compileFile(string $cppFile, string $objectFile): void { if ($this->hasObjectFileCache($cppFile)) { - $this->climate->darkGray('skip: ' . $cppFile . ', cache exists'); + $this->climate->darkGray('skip: '.$cppFile.', cache exists'); + return; } - $cmd = $this->cppCompiler . ' -c ' . $cppFile . ' -o ' . $objectFile; + $cmd = $this->cppCompiler.' -c '.$cppFile.' -o '.$objectFile; $this->addCompilationOption($cmd, false); $this->climate->comment($cmd); shell_exec($cmd); @@ -492,10 +507,10 @@ class Translator extends Preprocessor { $objectList = implode(' ', $objectFiles); $targetFile = $this->targetName; - if ($this->buildMode == 'ext' and !str_ends_with($targetFile, '.so')) { + if ('ext' == $this->buildMode and !str_ends_with($targetFile, '.so')) { $targetFile .= '.so'; } - $linkCmd = $this->cppCompiler . ' ' . $objectList . ' -o ' . $targetFile; + $linkCmd = $this->cppCompiler.' '.$objectList.' -o '.$targetFile; $this->addCompilationOption($linkCmd, true); $this->climate->comment($linkCmd); shell_exec($linkCmd); @@ -503,12 +518,12 @@ class Translator extends Preprocessor public function genFunctionDeclaration(string $file): void { - $code = '#include ' . PHP_EOL; + $code = '#include '.PHP_EOL; /** * @var FunctionDef $func */ foreach ($this->nativeFunctions as $name => $func) { - $code .= 'extern ' . $func->returnType . ' ' . self::PREFIX . $name . '('; + $code .= 'extern '.$func->returnType.' '.self::PREFIX.$name.'('; $argInfoList = $func->argInfoList; if ($argInfoList) { $list = []; @@ -516,22 +531,24 @@ class Translator extends Preprocessor $list[] = 'php::Object &this_'; } foreach ($argInfoList as $argInfo) { - $arg = $argInfo->type . ' ' . $argInfo->name; + $arg = $argInfo->type.' '.$argInfo->name; if ($argInfo->default) { - $arg .= ' = ' . $argInfo->default; + $arg .= ' = '.$argInfo->default; } $list[] = $arg; } $code .= implode(', ', $list); } - $code .= ');' . PHP_EOL; + $code .= ');'.PHP_EOL; } $code .= PHP_EOL; foreach ($this->nativeConstants as $name => $constant) { - $code .= 'extern ' . $constant->type . ' ' . $name . ';' . PHP_EOL; + $code .= 'extern '.$constant->type.' '.$name.';'.PHP_EOL; } + $code .= 'extern zend_class_entry *php_get_class_entry(int class_id, const char *class_name);'.PHP_EOL; + $this->writeFile($file, $code); } @@ -555,10 +572,10 @@ class Translator extends Preprocessor if ($this->useCppNamespace) { $ns = explode('\\', $ns); $ns = array_filter($ns, function ($v) { - return $v !== ''; + return '' !== $v; }); foreach ($ns as $name) { - $code .= 'namespace ' . $name . ' {' . PHP_EOL; + $code .= 'namespace '.$name.' {'.PHP_EOL; } $ns_end = str_repeat('}', count($ns)); $this->namespace = implode('::', $ns); @@ -574,13 +591,13 @@ class Translator extends Preprocessor $code .= $this->parseClass($v2); break; case 'Stmt_Const': - $this->parseConstDef($v2) . PHP_EOL; + $this->parseConstDef($v2).PHP_EOL; break; case 'Stmt_Function': - $code .= $this->parseFunction($v2) . PHP_EOL; + $code .= $this->parseFunction($v2).PHP_EOL; break; case 'Stmt_Use': - $code .= $this->parseUse($v2) . PHP_EOL; + $code .= $this->parseUse($v2).PHP_EOL; break; default: abort($v2); @@ -588,18 +605,19 @@ class Translator extends Preprocessor } $code .= $ns_end; $this->resetNamespace(); + return $code; } protected function genStubFile(string $file): void { - $genStubCmd = PHP_BINARY. ' ' . $this->rootPath . '/bin/gen_stub.php -f ' . $file; + $genStubCmd = PHP_BINARY.' '.$this->rootPath.'/bin/gen_stub.php -f '.$file; $output = shell_exec($genStubCmd); - $this->climate->info('generate stub file: ' . $file); + $this->climate->info('generate stub file: '.$file); $this->climate->comment($genStubCmd); - $stubFilenameWithoutExtension = str_replace([".stub.php", '.php'], "", $file); + $stubFilenameWithoutExtension = str_replace(['.stub.php', '.php'], '', $file); $headerFile = $this->getArgInfoHeaderFile($stubFilenameWithoutExtension, true); - if (!str_contains($output, "Saved")) { + if (!str_contains($output, 'Saved')) { $this->error("failed to generate arginfo header file: `$headerFile`, output: $output"); } $this->argInfoHeaderFiles[] = $headerFile; @@ -649,6 +667,7 @@ class Translator extends Preprocessor $this->fatalError($class, "Class `{$this->class}` uses a non-empty array as the default value for an property, and the constructor must be set."); } $this->resetClass(); + return $code; } @@ -659,8 +678,8 @@ class Translator extends Preprocessor public function getArgInfoHeaderFile(string $stubFilenameWithoutExtension, bool $relative = false): string { - $basename = self::PREFIX . basename($stubFilenameWithoutExtension); - $absPath = $this->getIncludeDir() . "/{$basename}_arginfo.h"; + $basename = self::PREFIX.basename($stubFilenameWithoutExtension); + $absPath = $this->getIncludeDir()."/{$basename}_arginfo.h"; if ($relative) { return ltrim($this->removeCommonPrefix($this->getIncludeDir(), $absPath), '/'); } else { @@ -673,7 +692,7 @@ class Translator extends Preprocessor $code = ''; $classDef = $this->classDef; foreach ($classDef->methods as $method) { - $code .= $methodCodes[$method->name] . PHP_EOL; + $code .= $methodCodes[$method->name].PHP_EOL; } $code .= PHP_EOL; @@ -686,28 +705,28 @@ class Translator extends Preprocessor $callParams = ''; foreach ($functionDef->argInfoList as $k => $argInfo) { if ($argInfo->default) { - $argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')'; + $argExpr = 'php::getCallArg('.$k.', '.$argInfo->default.')'; } else { - $argExpr = 'php::getCallArg(' . $k . ')'; + $argExpr = 'php::getCallArg('.$k.')'; } $expr = $this->convertExprFromType($argInfo->type, $argExpr); - $cppCode .= $this->getIndent() . $argInfo->type . ' arg_' . $argInfo->name . ' = ' . $expr . ';' . PHP_EOL; - $callParams .= 'arg_' . $argInfo->name . ','; + $cppCode .= $this->getIndent().$argInfo->type.' arg_'.$argInfo->name.' = '.$expr.';'.PHP_EOL; + $callParams .= 'arg_'.$argInfo->name.','; } if ($functionDef->method) { - $callParams = $functionDef->argInfoList ? 'this_, ' . rtrim($callParams, ',') : 'this_'; + $callParams = $functionDef->argInfoList ? 'this_, '.rtrim($callParams, ',') : 'this_'; } else { $callParams = $functionDef->argInfoList ? rtrim($callParams, ',') : ''; } - if ($functionDef->returnType !== self::TYPE_VOID) { - $cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(' . $callParams . ');' . PHP_EOL; - $cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL; + if (self::TYPE_VOID !== $functionDef->returnType) { + $cppCode .= $this->getIndent().'auto retval = '.$fn.'('.$callParams.');'.PHP_EOL; + $cppCode .= $this->getIndent().'php::move(retval, return_value);'.PHP_EOL; } else { - $cppCode .= $this->getIndent() . $fn . '(' . $callParams . ');' . PHP_EOL; + $cppCode .= $this->getIndent().$fn.'('.$callParams.');'.PHP_EOL; } - $cppCode .= '}' . PHP_EOL . PHP_EOL; + $cppCode .= '}'.PHP_EOL.PHP_EOL; return $cppCode; } @@ -715,27 +734,29 @@ class Translator extends Preprocessor protected function genMethodWrapper(ClassDef $classDef, MethodDef $methodDef): string { $name = $classDef->getNamespacedName(); - $cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL; - $cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL; + $cppCode = 'ZEND_METHOD('.$name.', '.$methodDef->name.'){'.PHP_EOL; + $cppCode .= $this->getIndent().self::TYPE_OBJECT.' this_(&execute_data->This);'.PHP_EOL; foreach ($classDef->properties as $property) { - if ($property->type === self::TYPE_ARRAY and $property->default and $property->default !== self::TYPE_ARRAY . '{}') { - $propOffset = self::PREFIX . $this->getPropertyOffset($property->name, $classDef->name, $classDef->namespace); - $cppCode .= $this->getIndent() . 'this_.getPropertyIndirect(' . $propOffset . ') = ' . $property->default . ';' . PHP_EOL; + if (self::TYPE_ARRAY === $property->type and $property->default and $property->default !== self::TYPE_ARRAY.'{}') { + $propOffset = self::PREFIX.$this->getPropertyOffset($property->name, $classDef->name, $classDef->namespace); + $cppCode .= $this->getIndent().'this_.getPropertyIndirect('.$propOffset.') = '.$property->default.';'.PHP_EOL; } } - $fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef); + $fn = self::PREFIX.$this->getNativeMethodName($classDef, $methodDef); $cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef); + return $cppCode; } private function genFunctionWrapper(FunctionDef $functionDef): string { $name = $functionDef->name; - $cppCode = 'ZEND_FUNCTION(' . $name . '){' . PHP_EOL; - $fn = self::PREFIX . $this->getNativeName($functionDef->name); + $cppCode = 'ZEND_FUNCTION('.$name.'){'.PHP_EOL; + $fn = self::PREFIX.$this->getNativeName($functionDef->name); $cppCode .= $this->genWrapperFunctionArgs($fn, $functionDef); + return $cppCode; } @@ -745,12 +766,11 @@ class Translator extends Preprocessor $name = $classDef->getNamespacedName(); $argsDef = $this->getRegisterClassFunctionArgDef($classDef); $param = $this->getRegisterClassFunctionArgs($classDef); - $cppCode .= 'zend_class_entry *' . $this->getRegisterClassFunction($name) . '(' . $argsDef . ') {' . PHP_EOL; - $cppCode .= $this->getIndent() . 'return register_class_' . $name . '(' . $param . ');' . PHP_EOL; - $cppCode .= '}' . PHP_EOL . PHP_EOL; + $cppCode .= 'zend_class_entry *'.$this->getRegisterClassFunction($name).'('.$argsDef.') {'.PHP_EOL; + $cppCode .= $this->getIndent().'return register_class_'.$name.'('.$param.');'.PHP_EOL; + $cppCode .= '}'.PHP_EOL.PHP_EOL; } - protected function genClassWrapper(ClassDef|InterfaceDef $classDef): string { $cppCode = ''; @@ -768,7 +788,7 @@ class Translator extends Preprocessor private function genClassNative(): string { - $code = 'class ' . $this->class . ' { '; + $code = 'class '.$this->class.' { '; $publicMethods = []; $protectedMethods = []; @@ -815,36 +835,37 @@ class Translator extends Preprocessor } if ($privateConstants) { - $code .= 'private:' . PHP_EOL; + $code .= 'private:'.PHP_EOL; $code .= $this->genClassConstantList($privateConstants); } if ($protectedConstants) { - $code .= 'protected:' . PHP_EOL; + $code .= 'protected:'.PHP_EOL; $code .= $this->genClassConstantList($protectedConstants); } if ($publicConstants) { - $code .= 'public:' . PHP_EOL; + $code .= 'public:'.PHP_EOL; $code .= $this->genClassConstantList($publicConstants); } if ($privateProperties) { - $code .= 'private:' . PHP_EOL; + $code .= 'private:'.PHP_EOL; $code .= $this->genClassPropertyList($privateProperties); } if ($protectedProperties) { - $code .= 'protected:' . PHP_EOL; + $code .= 'protected:'.PHP_EOL; $code .= $this->genClassPropertyList($protectedProperties); } if ($publicProperties) { - $code .= 'public:' . PHP_EOL; + $code .= 'public:'.PHP_EOL; $code .= $this->genClassPropertyList($publicProperties); } - $code .= '};' . PHP_EOL . PHP_EOL; + $code .= '};'.PHP_EOL.PHP_EOL; + return $code; } @@ -853,9 +874,10 @@ class Translator extends Preprocessor $headers = array_merge($this->globalHeaders, $this->localHeaders); $lines = []; foreach ($headers as $header) { - $lines[] = '#include <' . $header . '>'; + $lines[] = '#include <'.$header.'>'; } - return implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; + + return implode(PHP_EOL, $lines).PHP_EOL.PHP_EOL; } /** @@ -865,14 +887,15 @@ class Translator extends Preprocessor { $code = ''; foreach ($list as $const) { - $code .= $this->getIndent() . $this->genClassConstant($const); + $code .= $this->getIndent().$this->genClassConstant($const); } + return $code; } protected function genClassConstant(ConstantDef $const): string { - return 'static const ' . $const->type . ' ' . $const->name . ';' . PHP_EOL; + return 'static const '.$const->type.' '.$const->name.';'.PHP_EOL; } /** @@ -882,29 +905,32 @@ class Translator extends Preprocessor { $code = ''; foreach ($list as $prop) { - $code .= $this->getIndent() . $this->genClassProperty($prop); + $code .= $this->getIndent().$this->genClassProperty($prop); } + return $code; } protected function genClassProperty(PropertyDef $prop): string { - $code = $prop->type . ' ' . $prop->name; + $code = $prop->type.' '.$prop->name; if ($prop->default) { - $code .= ' = ' . $prop->default; + $code .= ' = '.$prop->default; } - return $code . ';' . PHP_EOL; + + return $code.';'.PHP_EOL; } protected function genFunction(string $name, string $returnType, array $args = [], array $lines = []): string { $_args = []; foreach ($args as $arg => $type) { - $_args[] = $type . ' ' . $arg; + $_args[] = $type.' '.$arg; } - $code = $returnType . ' ' . $name . '(' . implode(', ', $_args) . ') {' . PHP_EOL; - $code .= implode(PHP_EOL, $lines) . PHP_EOL; - $code .= '}' . PHP_EOL; + $code = $returnType.' '.$name.'('.implode(', ', $_args).') {'.PHP_EOL; + $code .= implode(PHP_EOL, $lines).PHP_EOL; + $code .= '}'.PHP_EOL; + return $code; } @@ -915,7 +941,7 @@ class Translator extends Preprocessor foreach ($v->consts as $const) { $constName = $this->parseIdentifier($const->name); if (isset($this->classDef->constants[$constName])) { - $this->fatalError($const, 'Cannot redefine class constant ' . $this->class . '::' . $constName); + $this->fatalError($const, 'Cannot redefine class constant '.$this->class.'::'.$constName); } $constInfo = new ConstantDef($constName, $flags, $type, $this->parseIdentifier($const->value)); $this->classDef->constants[$constInfo->name] = $constInfo; @@ -930,7 +956,7 @@ class Translator extends Preprocessor foreach ($v->props as $prop) { $propDef = new PropertyDef($this->parseIdentifier($prop->name), $flags, $type); if ($prop->default) { - if ($prop->default->getType() == 'Expr_Array' and count($prop->default->items) > 0) { + if ('Expr_Array' == $prop->default->getType() and count($prop->default->items) > 0) { $this->classDef->requireCtor = true; $propDef->type = self::TYPE_ARRAY; } @@ -961,6 +987,7 @@ class Translator extends Preprocessor foreach ($implements as $implement) { $list[] = $this->parseIdentifier($implement); } + return $list; } @@ -983,36 +1010,36 @@ class Translator extends Preprocessor $tmpArrayVar = $this->genTmpVarName(); $this->addLocalVar($tmpArrayVar, self::TYPE_ARRAY); - $code = 'if (' . $obj . '.instanceOf("IteratorAggregate")) {' . PHP_EOL; - $code .= $this->getIndent() . $tmpVar . ' = ' . $obj . '.exec("getIterator");' . PHP_EOL . '}' . PHP_EOL; - $code .= 'else if (' . $obj . '.instanceOf("Iterator")) {' . PHP_EOL; - $code .= $this->getIndent() . $tmpVar . ' = ' . $obj . ';' . PHP_EOL . '}'. PHP_EOL; + $code = 'if ('.$obj.'.instanceOf("IteratorAggregate")) {'.PHP_EOL; + $code .= $this->getIndent().$tmpVar.' = '.$obj.'.exec("getIterator");'.PHP_EOL.'}'.PHP_EOL; + $code .= 'else if ('.$obj.'.instanceOf("Iterator")) {'.PHP_EOL; + $code .= $this->getIndent().$tmpVar.' = '.$obj.';'.PHP_EOL.'}'.PHP_EOL; - $code .= 'if (' . $tmpVar . ') {'. PHP_EOL; + $code .= 'if ('.$tmpVar.') {'.PHP_EOL; - $this->indentLevel++; - $code .= $this->getIndent() . $tmpVar . '.exec("rewind");' . PHP_EOL; - $code .= $this->getIndent() . 'for (;' . $tmpVar . '.exec("valid"); ' . $tmpVar . '.exec("next")) {' . PHP_EOL; - $this->indentLevel++; + ++$this->indentLevel; + $code .= $this->getIndent().$tmpVar.'.exec("rewind");'.PHP_EOL; + $code .= $this->getIndent().'for (;'.$tmpVar.'.exec("valid"); '.$tmpVar.'.exec("next")) {'.PHP_EOL; + ++$this->indentLevel; $valueVar = $this->parseIdentifier($node->valueVar); $this->checkVar($node, $valueVar); - $code .= $this->getIndent() . ' ' . $valueVar . ' = ' . $tmpVar . '.exec("current");' . PHP_EOL; + $code .= $this->getIndent().' '.$valueVar.' = '.$tmpVar.'.exec("current");'.PHP_EOL; if ($node->keyVar) { $keyVar = $this->parseIdentifier($node->keyVar); $this->checkVar($node, $keyVar); - $code .= $this->getIndent() . ' ' . $keyVar . ' = ' . $tmpVar . '.exec("key");' . PHP_EOL; + $code .= $this->getIndent().' '.$keyVar.' = '.$tmpVar.'.exec("key");'.PHP_EOL; } $code .= $this->parseStmts($node->stmts); - $code .= '}' . PHP_EOL; - $this->indentLevel--; - $code .= $this->getIndent() . '} else {' . PHP_EOL; - $code .= $this->getIndent() . $tmpArrayVar . ' = php::call("get_object_vars", {' . $obj . '});' . PHP_EOL; + $code .= '}'.PHP_EOL; + --$this->indentLevel; + $code .= $this->getIndent().'} else {'.PHP_EOL; + $code .= $this->getIndent().$tmpArrayVar.' = php::call("get_object_vars", {'.$obj.'});'.PHP_EOL; $code .= $this->parseForeachArray($node, $tmpArrayVar); - $this->indentLevel--; - $code .= '}' . PHP_EOL; + --$this->indentLevel; + $code .= '}'.PHP_EOL; return $code; } -} \ No newline at end of file +} diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index 204c418d..9aade787 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -21,6 +21,16 @@ foreach ($this->classCeList as $ce): zend_class_entry * ; +// class entry +zend_class_entry *classMap) . ']' ?>; + +zend_class_entry *php_get_class_entry(int class_id, const char *class_name) { + if ([class_id] == nullptr) { + [class_id] = php::getClassEntrySafe(class_name); + } + return [class_id]; +} + // literal strings php::Var [] = { classes as $classDef): endforeach; endforeach; ?> + +// class entry +classMap as $class => $id): + ?> + = php::getClassEntry("escapeString($class) ?>"); + } void php_app_clean() {