fix(php): 修复异常处理和编译器逻辑问题

- 添加了 try-catch 异常处理的测试用例
- 实现了 isFullNameExpr 方法用于检查完全限定名称表达式
- 修复了编译器中的 break 语句缺失问题
- 重命名了 parseGlobal 方法参数以避免变量冲突
- 优化了 catch 类型检查逻辑,支持类名实例化检查
- 添加了 C++ 关键字到保留字常量列表
- 完善了项目配置文件 project.yml
- 添加了 instanceOf 符号方法
- 修复了多个 switch 语句中的 break 缺失问题
pull/1/head
韩天峰 4 months ago
parent d1a06ac8d4
commit ec98d1045d
  1. 12
      project.yml
  2. 5
      src/Php/AstNodeType.php
  3. 21
      src/Php/CompilerBase.php
  4. 5
      src/Php/Constants.php
  5. 6
      src/Php/Preprocessor.php
  6. 5
      src/Php/Symbol.php
  7. 3
      src/Php/Translator.php
  8. 0
      tests/aot/exception/001.phpt
  9. 0
      tests/aot/exception/002.phpt
  10. 21
      tests/aot/exception/003.phpt

@ -0,0 +1,12 @@
name: swoole-compiler
type: ext
version: 0.0.1
cxxflags: |
-std=c++14
-Wall
sources:
- ./src/Php
- ./src/Core
- ./src/functions.php
- ./src/gen_stub.php
- ./vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php

@ -55,6 +55,11 @@ trait AstNodeType
return $expr instanceof Node\Name;
}
protected function isFullNameExpr(NodeAbstract $expr): bool
{
return $expr instanceof Node\Name\FullyQualified;
}
protected function isNamedMethod(NodeAbstract $expr): bool
{
return $this->isIdExpr($expr);

@ -515,9 +515,10 @@ class CompilerBase extends \PhpAot\Core\Translator
case 'Expr_Yield':
case 'Expr_YieldFrom':
$this->fatalError($expr, 'The `' . $type . '` is not supported');
// no break
break;
default:
abort($expr);
break;
}
}
@ -926,6 +927,7 @@ class CompilerBase extends \PhpAot\Core\Translator
return $expr->hasAttribute('noLiteralString') ? $this->genCharPtr($expr->value) : $this->getLiteralString($expr->value);
default:
abort($expr);
break;
}
}
@ -1135,9 +1137,10 @@ class CompilerBase extends \PhpAot\Core\Translator
break;
case 'Stmt_Class':
$this->fatalError($v, 'Cannot declare class in function');
// no break
break;
default:
abort($v);
break;
}
$lines = array_merge($lines, $this->context->beforeStmtLines);
$this->context->beforeStmtLines = [];
@ -3224,9 +3227,9 @@ class CompilerBase extends \PhpAot\Core\Translator
return '"' . $this->escapeString($expr->value) . '"';
}
protected function parseGlobal(Node\Stmt\Global_ $v): string
protected function parseGlobal(Node\Stmt\Global_ $expr): string
{
foreach ($v->vars as $v) {
foreach ($expr->vars as $v) {
$name = $this->parseVariable($v);
if (!$this->hasGlobalVar($name)) {
$this->addGlobalVar($name, self::TYPE_VAR);
@ -3433,6 +3436,7 @@ class CompilerBase extends \PhpAot\Core\Translator
return '"' . $this->escapeString($class) . '::' . $this->escapeString($this->method) . '"';
default:
abort($expr);
break;
}
}
@ -3700,6 +3704,7 @@ class CompilerBase extends \PhpAot\Core\Translator
break;
default:
$this->fatalError($expr, 'Invalid include type');
break;
}
return 'php::include(' . $this->parseIdentifier($expr->expr) . ', ' . $type . ')';
@ -4356,7 +4361,13 @@ class CompilerBase extends \PhpAot\Core\Translator
$code .= $this->getIndent() . 'if (' . $var . ' && ';
foreach ($types as $type) {
$code .= 'php::instanceOf(' . $var . ', "' . $this->parseIdentifier($type) . '")';
if ($this->isNameExpr($type) or $this->isFullNameExpr($type)) {
$class = $this->getNamespacedClassName($this->parseIdentifier($type));
$ce = $this->getClassEntryPtr($class);
$code .= Symbol::instanceOf() . '(' . $var . ', ' . $ce . ')';
} else {
$this->fatalError($type, 'Unsupported catch type');
}
}
$code .= ') {' . PHP_EOL;

@ -33,6 +33,11 @@ class Constants
'if',
'bool',
'int',
'short',
'long',
'unsigned',
'void',
'signed',
'double',
'float',
'false',

@ -143,9 +143,10 @@ class Preprocessor extends CompilerBase
break;
case 'Stmt_Expression':
$this->foundStrayCode($v);
// no break
break;
default:
$this->fatalError($v, 'Unsupported statement: ' . $type);
break;
}
}
}
@ -451,9 +452,10 @@ class Preprocessor extends CompilerBase
break;
case 'Stmt_Expression':
$this->foundStrayCode($v);
// no break
break;
default:
abort($v);
break;
}
}

@ -20,6 +20,11 @@ class Symbol
return 'php::setStaticProperty';
}
public static function instanceOf(): string
{
return 'php::instanceOf';
}
public static function getCalledCe(): string
{
return CompilerBase::PREFIX . 'get_called_ce(this_)';

@ -857,6 +857,7 @@ class Translator extends Preprocessor
break;
default:
abort($v);
break;
}
}
@ -988,6 +989,7 @@ class Translator extends Preprocessor
break;
default:
abort($v2);
break;
}
}
$code .= $ns_end;
@ -1162,6 +1164,7 @@ class Translator extends Preprocessor
break;
default:
abort($v);
break;
}
}
$code = $this->genNativeMethod($methodCodes);

@ -0,0 +1,21 @@
--TEST--
try catch 2
--FILE--
<?php
namespace PhpTest {
class MyException extends \Exception {
}
}
namespace {
function main() {
try {
throw new \PhpTest\MyException('test error');
} catch (\PhpTest\MyException $e) {
var_dump($e->getMessage());
}
}
}
?>
--EXPECT--
string(10) "test error"
Loading…
Cancel
Save