refactor(Php): 重构类定义和编译器实现

- 修改 ClassDef 中 methods、properties 和 constants 的类型为关联数组
- 在 CompilerBase 中添加 TYPE_VOID 常量并修改函数名获取逻辑
- 将 escapeClass 方法改为小写转换
- 使用 climate 库替换日志输出方法
- 更新 MethodDef 构造函数以支持返回类型
- 重构 Translator 中的类包装器生成逻辑
- 实现原生方法包装器和类包装器功能
- 修改常量和属性存储方式为键值对形式
- 添加方法包装器以支持返回类型处理
pull/1/head
韩天峰 8 months ago
parent d21e7c13bf
commit 5fd9215509
  1. 6
      src/Php/ClassDef.php
  2. 24
      src/Php/CompilerBase.php
  3. 7
      src/Php/MethodDef.php
  4. 73
      src/Php/Translator.php

@ -6,15 +6,15 @@ class ClassDef
{
public string $name;
/**
* @var array< MethodDef>
* @var array<string, MethodDef>
*/
public array $methods = [];
/**
* @var array<PropertyDef>
* @var array<string, PropertyDef>
*/
public array $properties = [];
/**
* @var array<ConstantDef>
* @var array<string, ConstantDef>
*/
public array $constants = [];
public string $namespace = '';

@ -31,6 +31,7 @@ class CompilerBase extends \PhpAot\Core\Translator
public const string TYPE_ARRAY = 'php::Array';
public const string TYPE_STR = 'php::Str';
public const string TYPE_REF = 'php::Var';
public const string TYPE_VOID = 'void';
public const string VALUE_NAN = 'std::numeric_limits<double>::quiet_NaN()';
public const string VALUE_INF = 'std::numeric_limits<double>::infinity()';
@ -215,14 +216,19 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->namespace = '';
}
protected function getFunctionName(Node $v): string
protected function getFunctionName(FunctionLike $v): string
{
$names[] = $this->escapeFunction($this->parseIdentifier($v->name));
if ($this->namespace) {
$names[] = $this->escapeNamespace($this->namespace);
return $this->getNativeFunctionName($this->parseIdentifier($v->name), $this->namespace, $this->class);
}
protected function getNativeFunctionName(string $fn, string $ns = '', string $class = ''): string
{
$names[] = $this->escapeFunction($fn);
if ($ns) {
$names[] = $this->escapeNamespace($ns);
}
if ($this->class) {
$names[] = $this->escapeClass($this->class);
if ($class) {
$names[] = $this->escapeClass($class);
}
return implode(self::NAMESPACE_SEPARATOR, array_reverse($names));
}
@ -1785,7 +1791,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function escapeClass(string $class): string
{
return $class;
return strtolower($class);
}
protected function unescapeVarName(string $name): string
@ -1950,8 +1956,8 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function formatCppCode(string $file): void
{
$cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file;
$this->writeLog('formatting ' . $file . '...');
$this->writeLog($cmd);
$this->climate->info('formatting ' . $file );
$this->climate->comment($cmd);
shell_exec($cmd);
}

@ -4,13 +4,14 @@ namespace PhpAot\Php;
class MethodDef
{
public string $name;
public string $flags;
public int $flags;
public string $returnType;
public function __construct(string $name, string $flags)
public function __construct(string $name, int $flags, string $returnType)
{
$this->name = $name;
$this->flags = $flags;
$this->returnType = $returnType;
}
}

@ -165,22 +165,9 @@ class Translator extends Preprocessor
}
foreach ($this->classesDefineInFile as $classDef) {
$name = $classDef->getNamespacedName();
if ($classDef->extends) {
$parentName = 'zend_class_entry *parent_ce';
$param = 'parent_ce';
} else {
$parentName = '';
$param = '';
}
$cppCode .= 'zend_class_entry *' . $this->getRegisterClassFunction($name) . '(' . $parentName . ') {' . PHP_EOL;
$cppCode .= $this->getIndent() . 'return ' . $this->getRegisterClassFunction($name) . '(' . $param . ');' . PHP_EOL;
$cppCode .= '}' . PHP_EOL . PHP_EOL;
$cppCode .= $this->genClassWrapper($classDef);
}
$cppCode .= PHP_EOL;
// include + extern global vars + function impl
return $this->genIncludeHeaderFiles() . $cppCode;
}
@ -362,6 +349,11 @@ class Translator extends Preprocessor
return strtolower($this->parseIdentifier($v->name));
}
protected function getNativeMethodName(ClassDef $classDef, MethodDef $methodDef): string
{
return $this->getNativeFunctionName($methodDef->name, $classDef->namespace, $classDef->name);
}
protected function parseNamespace(Node\Stmt\Namespace_ $node): string
{
$ns = $this->parseIdentifier($node->name);
@ -450,7 +442,7 @@ class Translator extends Preprocessor
abort($v);
}
}
$code = $this->genZendClass($methodCodes);
$code = $this->genNativeMethod($methodCodes);
$this->class = '';
return $code;
}
@ -466,7 +458,7 @@ class Translator extends Preprocessor
}
}
protected function genZendClass($methodCodes): string
protected function genNativeMethod($methodCodes): string
{
$code = '';
$classDef = $this->classDef;
@ -476,6 +468,48 @@ class Translator extends Preprocessor
return $code;
}
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;
$fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef);
if ($methodDef->returnType !== self::TYPE_VOID) {
$cppCode .= $this->getIndent() . 'auto retval = ' . $fn . '(this_);' . PHP_EOL;
$cppCode .= $this->getIndent() . 'php::move(retval, return_value);' . PHP_EOL;
} else {
$cppCode .= $this->getIndent() . $fn . '(this_);' . PHP_EOL;
}
$cppCode .= '}' . PHP_EOL . PHP_EOL;
return $cppCode;
}
protected function genClassWrapper(ClassDef $classDef): string
{
$cppCode = '';
$name = $classDef->getNamespacedName();
if ($classDef->extends) {
$parentName = 'zend_class_entry *parent_ce';
$param = 'parent_ce';
} else {
$parentName = '';
$param = '';
}
$cppCode .= 'zend_class_entry *' . $this->getRegisterClassFunction($name) . '(' . $parentName . ') {' . PHP_EOL;
$cppCode .= $this->getIndent() . 'return ' . $this->getRegisterClassFunction($name) . '(' . $param . ');' . PHP_EOL;
$cppCode .= '}' . PHP_EOL . PHP_EOL;
$methods = $classDef->methods;
foreach ($methods as $methodDef) {
$cppCode .= $this->genMethodWrapper($classDef, $methodDef);
}
return $cppCode;
}
private function genClassNative(): string
{
$code = 'class ' . $this->class . ' { ';
@ -624,7 +658,7 @@ class Translator extends Preprocessor
$type = $v->type ? $this->getTypeFromZendType($this->parseIdentifier($v->type)) : self::TYPE_VAR;
foreach ($v->consts as $const) {
$constInfo = new ConstantDef($this->parseIdentifier($const->name), $flags, $type, $this->parseIdentifier($const->value));
$this->classDef->constants[] = $constInfo;
$this->classDef->constants[$constInfo->name] = $constInfo;
}
}
@ -638,7 +672,7 @@ class Translator extends Preprocessor
if ($prop->default) {
$propDef->default = $this->parseIdentifier($prop->default);
}
$this->classDef->properties[] = $propDef;
$this->classDef->properties[$propDef->name] = $propDef;
}
}
@ -646,7 +680,8 @@ class Translator extends Preprocessor
{
$name = $this->getMethodName($v);
$flags = $v->flags;
$methodDef = new MethodDef($name, $flags);
$returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID;
$methodDef = new MethodDef($name, $flags, $returnType);
$this->classDef->methods[$name] = $methodDef;
$methodCodes[$name] = $this->parseFunction($v);
}

Loading…
Cancel
Save