diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index f01faceb..3360b4de 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1071,7 +1071,7 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont return ltrim($funcName, '\\'); } if (isset($this->useFunctions[$funcName])) { - return $this->useFunctions[$funcName] . '\\' . $funcName; + return $this->useFunctions[$funcName]; } return $funcName; } @@ -3082,7 +3082,7 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont $possibleFunctionNames[] = $this->escapeNamespace($this->namespace) . self::NAMESPACE_SEPARATOR . $this->escapeName($funcName); } if (isset($this->useFunctions[$funcName])) { - $possibleFunctionNames[] = $this->escapeNamespace($this->useFunctions[$funcName]) . self::NAMESPACE_SEPARATOR . $this->escapeName($funcName); + $possibleFunctionNames[] = $this->escapeNamespace($this->useFunctions[$funcName]); } // 复杂命名空间规则,组合命名空间 // 例子:use foo\bar; bar\fn(); @@ -6705,11 +6705,10 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont if ($type === Node\Stmt\Use_::TYPE_FUNCTION) { $lastIndex = strrpos($id, '\\'); $fn = substr($id, $lastIndex + 1); - $ns = substr($id, 0, $lastIndex); if ($use->alias) { - $this->useFunctions[$use->alias->toString()] = $ns; + $this->useFunctions[$use->alias->toString()] = $id; } else { - $this->useFunctions[$fn] = $ns; + $this->useFunctions[$fn] = $id; } } elseif ($type === Node\Stmt\Use_::TYPE_CONSTANT) { $lastIndex = strrpos($id, '\\'); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 4148aa7d..37e8189a 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2433,7 +2433,11 @@ CODE; $declares = $v->declares; foreach ($declares as $declare) { $key = $this->parseIdentifier($declare->key); - $value = $this->parseIdentifier($declare->value); + $value = match (true) { + $declare->value instanceof Node\Scalar\String_ => $declare->value->value, + $declare->value instanceof Node\Scalar\Int_ => (string) $declare->value->value, + default => $this->parseIdentifier($declare->value), + }; if ($key === 'ticks') { $this->fatalError($v, 'declare(ticks=1) is not supported'); } elseif ($key === 'encoding') { diff --git a/tests/aot/array/destructure-function-return.phpt b/tests/aot/array/destructure-function-return.phpt new file mode 100644 index 00000000..26387258 --- /dev/null +++ b/tests/aot/array/destructure-function-return.phpt @@ -0,0 +1,26 @@ +--TEST-- +array destructuring from function return values +--FILE-- + +--EXPECT-- +make:alpha +string(5) "alpha" +string(5) "ALPHA" +string(17) "left:middle:right" diff --git a/tests/aot/basic/declare-encoding-utf8.phpt b/tests/aot/basic/declare-encoding-utf8.phpt new file mode 100644 index 00000000..fb72dac0 --- /dev/null +++ b/tests/aot/basic/declare-encoding-utf8.phpt @@ -0,0 +1,13 @@ +--TEST-- +declare encoding UTF-8 is accepted +--FILE-- + +--EXPECT-- +encoding-ok diff --git a/tests/aot/basic/shell-exec.phpt b/tests/aot/basic/shell-exec.phpt new file mode 100644 index 00000000..da18563a --- /dev/null +++ b/tests/aot/basic/shell-exec.phpt @@ -0,0 +1,14 @@ +--TEST-- +shell execution operator returns command output +--FILE-- + +--EXPECT-- +string(9) "hello-aot" diff --git a/tests/aot/closure/static-closure-use.phpt b/tests/aot/closure/static-closure-use.phpt new file mode 100644 index 00000000..e1ee8067 --- /dev/null +++ b/tests/aot/closure/static-closure-use.phpt @@ -0,0 +1,37 @@ +--TEST-- +static closure captures values and references through use +--FILE-- + +--EXPECT-- +int(15) +int(1) +int(2) +array(2) { + [0]=> + string(5) "first" + [1]=> + string(6) "second" +} diff --git a/tests/aot/exception/throw-expression.phpt b/tests/aot/exception/throw-expression.phpt new file mode 100644 index 00000000..a7afcc56 --- /dev/null +++ b/tests/aot/exception/throw-expression.phpt @@ -0,0 +1,38 @@ +--TEST-- +throw expression in coalesce and ternary +--FILE-- +getMessage() . "\n"; + } + + try { + pick_value(false); + } catch (Throwable $e) { + echo get_class($e) . ':' . $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +string(7) "present" +string(2) "ok" +InvalidArgumentException:missing +RuntimeException:bad diff --git a/tests/aot/functions/print-expression-return.phpt b/tests/aot/functions/print-expression-return.phpt new file mode 100644 index 00000000..9f1671fb --- /dev/null +++ b/tests/aot/functions/print-expression-return.phpt @@ -0,0 +1,20 @@ +--TEST-- +print expression returns 1 and can be composed +--FILE-- + +--EXPECT-- +hello +int(1) +cond +branch diff --git a/tests/aot/namespace/group-use-mixed.phpt b/tests/aot/namespace/group-use-mixed.phpt new file mode 100644 index 00000000..b49f23f8 --- /dev/null +++ b/tests/aot/namespace/group-use-mixed.phpt @@ -0,0 +1,33 @@ +--TEST-- +Mixed group use imports for class, function, and constant +--FILE-- + +--EXPECT-- +string(7) "[mixed]" +string(11) "label:mixed" diff --git a/tests/aot/namespace/use-function-alias.phpt b/tests/aot/namespace/use-function-alias.phpt new file mode 100644 index 00000000..b8256a22 --- /dev/null +++ b/tests/aot/namespace/use-function-alias.phpt @@ -0,0 +1,29 @@ +--TEST-- +use function alias resolves imported function name +--FILE-- + +--EXPECT-- +string(3) "aot" diff --git a/tests/aot/operator/cast-expression-side-effects.phpt b/tests/aot/operator/cast-expression-side-effects.phpt new file mode 100644 index 00000000..4efadcf7 --- /dev/null +++ b/tests/aot/operator/cast-expression-side-effects.phpt @@ -0,0 +1,38 @@ +--TEST-- +cast operands are evaluated once +--FILE-- + 'aot']); + var_dump($object->name); + + $array = (array) make_value('array', $object); + var_dump($array['name']); +} +?> +--EXPECT-- +make:int +int(42) +make:float +float(2.5) +make:string +string(3) "123" +make:bool +bool(false) +make:object +string(3) "aot" +make:array +string(3) "aot" diff --git a/tests/aot/static/static-vars-multiple-init.phpt b/tests/aot/static/static-vars-multiple-init.phpt new file mode 100644 index 00000000..413a6d02 --- /dev/null +++ b/tests/aot/static/static-vars-multiple-init.phpt @@ -0,0 +1,42 @@ +--TEST-- +multiple static variables initialize independently once +--FILE-- + +--EXPECT-- +init:a:10 +init:b:20 +array(2) { + [0]=> + int(11) + [1]=> + int(22) +} +array(2) { + [0]=> + int(13) + [1]=> + int(26) +} diff --git a/tests/aot/stdlib/class-exists-class-constant.phpt b/tests/aot/stdlib/class-exists-class-constant.phpt new file mode 100644 index 00000000..42a7a37c --- /dev/null +++ b/tests/aot/stdlib/class-exists-class-constant.phpt @@ -0,0 +1,46 @@ +--TEST-- +class/interface/trait/enum exists with ::class names +--FILE-- + ExistsNames\ExistingClass::class, + 'interface' => ExistsNames\ExistingInterface::class, + 'trait' => ExistsNames\ExistingTrait::class, + 'enum' => ExistsNames\ExistingEnum::class, + ]; + + var_dump(class_exists(ExistsNames\pick_name($names, 'class'))); + var_dump(interface_exists(ExistsNames\pick_name($names, 'interface'))); + var_dump(trait_exists(ExistsNames\pick_name($names, 'trait'))); + var_dump(enum_exists(ExistsNames\pick_name($names, 'enum'))); + var_dump(class_exists('ExistsNames\\MissingClass', false)); + } +} +?> +--EXPECT-- +pick:class +bool(true) +pick:interface +bool(true) +pick:trait +bool(true) +pick:enum +bool(true) +bool(false) diff --git a/tests/aot/stdlib/method-property-exists-dynamic.phpt b/tests/aot/stdlib/method-property-exists-dynamic.phpt new file mode 100644 index 00000000..9d78fedd --- /dev/null +++ b/tests/aot/stdlib/method-property-exists-dynamic.phpt @@ -0,0 +1,40 @@ +--TEST-- +method_exists and property_exists with dynamic names +--FILE-- + +--EXPECT-- +choose:method +bool(true) +bool(false) +choose:property +bool(true) +bool(true)