TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
9.8 KiB
172 lines
9.8 KiB
# TypePHP change log
|
|
|
|
## 0.8.0
|
|
|
|
### Breaking: native scalar storage is now the default
|
|
|
|
`use native_types` has been removed. Inferred `int`, `float`, and `bool`
|
|
locals now use `php::Int`, `php::Float`, and `php::Bool` by default. Their
|
|
storage type is fixed and the compiler never promotes one of these locals to
|
|
`php::Var` merely because a later operation needs dynamic PHP semantics.
|
|
|
|
Two explicit escape hatches remain:
|
|
|
|
- `use varint_types` is a file-level mode that stores inferred integer values
|
|
in `php::Var`, preserving PHP's overflow-to-float, non-integral division,
|
|
and other Zend integer arithmetic behavior. It does not box `float` or
|
|
`bool` locals.
|
|
- `std::any($value)` erases the static type of that individual expression, so
|
|
a variable initialized from it uses `php::Var` and may participate in PHP
|
|
reference or dynamic-value operations.
|
|
|
|
For example, `$i = 100` is now permanently an integer local. Reusing `$i` as a
|
|
`foreach` key is rejected because PHP keys have type `int|string`; write
|
|
`$i = std::any(100)` or select `use varint_types` if this reuse is intentional.
|
|
Projects must remove `use native_types` and add the new compatibility mode only
|
|
to files that genuinely depend on Zend integer widening semantics.
|
|
|
|
Fixed `int`, `float`, `bool`, `string`, and `array` locals now use typed native
|
|
references. A stable local alias and an exact by-reference parameter on a
|
|
statically resolved TypePHP call lower directly to C++ `T&`; this path does not
|
|
box the value or allocate a Zend reference. Bindings must be unconditional,
|
|
one-time, function-local, and non-escaping. Rebinding, `unset`, reference
|
|
capture/return, and storing such a reference into PHP storage are rejected.
|
|
|
|
Fixed `int`, `float`, `bool`, `string`, and `array` Native Class properties can
|
|
now be passed directly to an exactly matching reference parameter on a
|
|
statically resolved call. This lowers to a call-scoped C++ `T&` while precisely
|
|
rooting the Native receiver. It does not enable general PHP references for the
|
|
field: `=&`, `std::ref()`, dynamic calls, and escaping reference forms remain
|
|
forbidden. Explicit `any` properties continue to use the dynamic Zend reference
|
|
model.
|
|
|
|
Dynamic calls and Closures retain the existing Zend reference path and require
|
|
explicit `std::ref()` / `toRef()`. A call-scoped bridge validates the value on
|
|
write-back and rejects an escaping temporary reference. Use `std::any()` for
|
|
unrestricted PHP reference identity. Fixed object/resource/stream,
|
|
high-precision, Native/typed-object, Box, and `std`-container locals remain
|
|
non-referenceable because those types already carry identity/handle semantics.
|
|
Typed properties and PHP array elements continue to use Zend references and
|
|
their normal type-source behavior.
|
|
|
|
TypePHP is always strict. Project sources no longer need
|
|
`declare(strict_types=1)`; the directive remains accepted as a redundant PHP
|
|
compatibility declaration, while `strict_types=0` is rejected.
|
|
|
|
### Breaking: compile-time API namespace cleanup
|
|
|
|
TypePHP compile-time APIs now occupy only two global class symbols:
|
|
|
|
- `Type::*` describes types used by extension-method metadata. It does not
|
|
execute conversions or other built-in operations.
|
|
- `std::*` contains TypePHP built-in compile-time functions.
|
|
|
|
As with PHP class and method names, the `std` / `Type` class names and `std`
|
|
method names are case-insensitive. `Type::Int` and the other `Type` members are
|
|
class constants, so their constant names remain case-sensitive under PHP rules.
|
|
|
|
The former global compile-time functions have changed as follows:
|
|
|
|
| Before 0.8 | Since 0.8 | Notes |
|
|
| --- | --- | --- |
|
|
| `any($value)` | `std::any($value)` | Erases the static type to `mixed/any`. |
|
|
| `refval($target)` | `std::ref($target)` | Explicit reference wrapper for call arguments. |
|
|
| `expected($condition)` | `std::expected($condition)` | Emits the `EXPECTED(...)` branch hint. |
|
|
| `unexpected($condition)` | `std::unexpected($condition)` | Emits the `UNEXPECTED(...)` branch hint. |
|
|
| `objval($value, Foo::class)` | `std::object($value, Foo::class)` | Restores concrete object type information; the equivalent keyword method remains available as `$value->toObject(Foo::class)`. |
|
|
| `std::ordered_map($keyType, $valueType)` | `std::orderedMap($keyType, $valueType)` | Uses the standard camelCase spelling for a multi-word method name. |
|
|
|
|
No compatibility functions are installed in the global namespace. Applications
|
|
may define and call their own `any()`, `refval()`, `expected()`, `unexpected()`,
|
|
and `objval()` functions without being intercepted by the compiler.
|
|
|
|
`std::ref()` retains the previous reference-wrapper restrictions: its target
|
|
must be a variable, array element, or object property, and it is only valid as a
|
|
call argument wrapper. `toRef()` remains the equivalent keyword method.
|
|
|
|
All projects using the old spellings must update their source and rebuild.
|
|
|
|
### Compatibility policy before 1.0
|
|
|
|
TypePHP is still pre-1.0 software. Public compiler APIs, TypePHP-specific source
|
|
syntax, generated-code interfaces, configuration, and packaging may change
|
|
between minor releases. Breaking changes will be documented here, but users
|
|
should review the change log and run their full test suite before upgrading.
|
|
|
|
---
|
|
|
|
## 0.8.0(中文)
|
|
|
|
### 破坏性变更:默认使用原生标量存储
|
|
|
|
`use native_types` 已移除。推断出的 `int`、`float`、`bool` 局部变量现在默认分别
|
|
使用 `php::Int`、`php::Float`、`php::Bool`。这些变量的存储类型一旦确定便不会因为
|
|
后续操作需要 PHP 动态语义而被编译器自动提升为 `php::Var`。
|
|
|
|
只保留两个显式出口:
|
|
|
|
- `use varint_types` 是文件级模式,使推断出的整数使用 `php::Var`,保留 PHP 的
|
|
整数溢出转浮点、整数除法产生非整数结果等 Zend 算术语义;它不会装箱 `float`
|
|
或 `bool`。
|
|
- `std::any($value)` 只擦除该表达式的静态类型。以它初始化的变量使用 `php::Var`,
|
|
可参与引用或其他动态值操作。
|
|
|
|
例如 `$i = 100` 现在固定为整数局部变量。由于 PHP 的 foreach key 类型为
|
|
`int|string`,之后复用 `$i` 作为 key 会在编译期报错;确需复用时,应写成
|
|
`$i = std::any(100)` 或在文件中声明 `use varint_types`。升级项目必须删除
|
|
`use native_types`,并且只为真正依赖 Zend 整数扩展语义的文件添加新兼容模式。
|
|
|
|
固定 `int`、`float`、`bool`、`string`、`array` 局部变量现在使用强类型原生引用。
|
|
稳定的局部别名,以及静态可解析 TypePHP 调用上的精确引用参数,会直接生成 C++ `T&`,
|
|
不装箱、不创建 Zend reference。绑定必须位于函数顶层、只发生一次且不得逃逸;重新绑定、
|
|
`unset`、引用捕获/返回,或把引用存入 PHP 槽位都会在编译期拒绝。
|
|
|
|
Native Class 中固定类型为 `int`、`float`、`bool`、`string`、`array` 的属性,现在也可
|
|
直接传给静态可解析调用中类型完全匹配的引用参数。编译器将其生成为仅在本次调用期间
|
|
有效的 C++ `T&`,同时精确保活 Native 接收对象;这并不会为字段开放通用 PHP 引用,
|
|
`=&`、`std::ref()`、动态调用及其他可能逃逸的引用形式仍被禁止。显式声明为 `any` 的
|
|
属性继续使用动态 Zend reference 模型。
|
|
|
|
动态调用与 Closure 继续使用既有 Zend reference 路径,并要求显式使用 `std::ref()` /
|
|
`toRef()`。调用级 bridge 在返回时检查类型并拒绝临时引用逃逸;需要完整 PHP 引用身份时
|
|
应使用 `std::any()`。固定 object/resource/stream、高精度值、Native/typed object、Box
|
|
和 `std` 容器仍然禁止取引用,因为这些类型本身已有 identity/handle 语义。Typed
|
|
Property 与 PHP 数组元素继续使用 Zend reference 及其 type source 约束。
|
|
|
|
TypePHP 始终使用严格类型,项目源码不再需要 `declare(strict_types=1)`。该声明仍作为
|
|
冗余的 PHP 兼容语法被接受,而 `strict_types=0` 会被拒绝。
|
|
|
|
### 破坏性变更:整理编译期 API 命名空间
|
|
|
|
TypePHP 编译期 API 现在只占用两个全局类符号:
|
|
|
|
- `Type::*` 仅描述扩展方法元数据等场景使用的类型,不执行类型转换或其他内置操作。
|
|
- `std::*` 承载 TypePHP 内置编译期函数。
|
|
|
|
遵循 PHP 的类名与方法名规则,`std` / `Type` 类名以及 `std` 方法名均不区分
|
|
大小写。`Type::Int` 等成员属于类常量,因此其常量名仍按 PHP 规则区分大小写。
|
|
|
|
原全局编译期函数迁移如下:
|
|
|
|
| 0.8 之前 | 0.8 起 | 说明 |
|
|
| --- | --- | --- |
|
|
| `any($value)` | `std::any($value)` | 将静态类型降级为 `mixed/any`。 |
|
|
| `refval($target)` | `std::ref($target)` | 调用参数的显式引用包装器。 |
|
|
| `expected($condition)` | `std::expected($condition)` | 生成 `EXPECTED(...)` 分支提示。 |
|
|
| `unexpected($condition)` | `std::unexpected($condition)` | 生成 `UNEXPECTED(...)` 分支提示。 |
|
|
| `objval($value, Foo::class)` | `std::object($value, Foo::class)` | 恢复具体对象类型;仍可使用等价关键词方法 `$value->toObject(Foo::class)`。 |
|
|
| `std::ordered_map($keyType, $valueType)` | `std::orderedMap($keyType, $valueType)` | 多单词方法统一使用 camelCase 命名。 |
|
|
|
|
TypePHP 不在全局命名空间安装兼容函数。应用可以自行定义并正常调用
|
|
`any()`、`refval()`、`expected()`、`unexpected()` 和 `objval()`,编译器不会拦截。
|
|
|
|
`std::ref()` 延续原引用包装限制:目标必须是变量、数组元素或对象属性,且只能作为
|
|
调用参数包装器使用。`toRef()` 仍是等价的关键词方法。
|
|
|
|
使用旧写法的项目必须修改源码并重新编译。
|
|
|
|
### 1.0 之前的兼容性策略
|
|
|
|
TypePHP 目前仍处于 1.0 之前。公开编译器 API、TypePHP 专有源码接口、生成代码接口、
|
|
配置和打包方式都可能在次版本中发生变化。破坏性变更会记录在本文件中;升级前请阅读
|
|
变更记录,并运行项目的完整测试。
|
|
|