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.
 
 

37 lines
5.0 KiB

<!doctype html><html lang="zh"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>AST 转换(Lowering)</title>
<script src="../script/mermaid.min.js"></script>
<script>document.addEventListener('DOMContentLoaded',function(){if(window.mermaid)mermaid.initialize({startOnLoad:true});});</script>
<style>
:root{--bg:#0f1117;--fg:#e6e6e6;--muted:#9aa0aa;--accent:#6ea8fe;--card:#171a21;--border:#262b36;}
*{box-sizing:border-box}
body{margin:0;font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;background:var(--bg);color:var(--fg);line-height:1.65}
.wrap{max-width:900px;margin:0 auto;padding:32px 24px 80px}
h1,h2,h3{color:#fff;line-height:1.3;margin-top:1.6em}
h1{border-bottom:1px solid var(--border);padding-bottom:.3em}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
code{background:#0b0d12;padding:.15em .4em;border-radius:4px;font-size:.9em}
pre{background:#0b0d12;border:1px solid var(--border);border-radius:8px;padding:14px;overflow:auto}
pre code{background:none;padding:0}
table{border-collapse:collapse;width:100%;margin:1em 0}
th,td{border:1px solid var(--border);padding:8px 10px;text-align:left}
th{background:var(--card)}
blockquote{border-left:3px solid var(--accent);margin:1em 0;padding:.2em 1em;color:var(--muted);background:var(--card)}
hr{border:none;border-top:1px solid var(--border);margin:2em 0}
</style></head>
<body><div class="wrap"><h1>AST 转换(Lowering)</h1>
<p><code>doConvert()</code> 遍历 AST 时,<code>src/Transform/Visitor.php</code> 作为 <code>NodeVisitor</code> 挂载在遍历链上,对节点做<strong>编译期改写(lowering)</strong>——把 PHP 8.x 的高层语法(属性钩子、构造函数提升、getter、编译期属性等)降级为编译器能直接翻译的普通结构。</p>
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Transform\Visitor.php#L19-L36">src/Transform/Visitor.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L2462">src/Translator.php</a></p>
<h2>两个遍历钩子</h2>
<p><code>Visitor</code> 实现 <code>enterNode()</code><code>leaveNode()</code> 两阶段处理:</p>
<ul><li><strong>enterNode</strong>(进入节点前):校验 + 即时 lowering。依次调用 <code>CompileTimeAttribute::validateNode</code><code>FunctionAttributeLowering::lower</code><code>GetterLowering::validateTarget</code><code>PropertyMethodLowering::validateTarget</code><code>ConstructorLowering::validateTarget</code></li><li><strong>leaveNode</strong>(离开节点后):对函数/闭包做 <code>ParameterValidationLowering</code>;对类/属性做 <code>PropertyHookLowering</code><code>GetterLowering</code><code>PropertyMethodLowering</code>,把钩子属性、getter、提升属性改写成方法或标记。</li></ul>
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Transform\Visitor.php#L28-L80">src/Transform/Visitor.php</a></p>
<h2>Lowering 算子清单</h2>
<table><thead><tr><th></th><th>作用</th></tr></thead><tbody><tr><td><code>CompileTimeAttribute</code> / <code>CompileTimeAttributeRegistry</code></td><td>识别并校验编译期属性(如 <code>Any</code><code>MustUse</code></td></tr><tr><td><code>FunctionAttributeLowering</code></td><td>处理函数上的编译期属性</td></tr><tr><td><code>ConstructorLowering</code></td><td>处理构造函数提升参数</td></tr><tr><td><code>GetterLowering</code></td><td><code>get</code> 钩子属性 → getter 方法</td></tr><tr><td><code>PropertyHookLowering</code></td><td><code>get</code>/<code>set</code> 钩子属性 → 访问器方法</td></tr><tr><td><code>PropertyMethodLowering</code></td><td>属性 ↔ 方法互转</td></tr><tr><td><code>ParameterValidationLowering</code></td><td>参数类型校验,拒绝箭头函数误用</td></tr><tr><td><code>PrinterLowering</code> / <code>ValidateLowering</code></td><td>打印/校验相关降级</td></tr><tr><td><code>ArrayableLowering</code> / <code>NotEmptyLowering</code> / <code>NotNullLowering</code></td><td>特定表达式降级</td></tr><tr><td><code>RuntimeAttributeFactoryLowering</code></td><td>运行时工厂属性(遍历链上独立挂载)</td></tr></tbody></table>
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Transform">src/Transform/</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L2467">src/Translator.php</a></p>
<h2>顺序意义</h2>
<p>Lowering 必须早于 C++ 生成:例如属性钩子若不先降级成方法,后续 <code>genClassWrapper</code> 就无法生成对应的 C++ 访问逻辑。它处在 <a href="pages/parser.html">解析器与 AST</a> 之后、<a href="pages/generator.html">代码生成</a> 之前。</p>
<h2>相关阅读</h2>
<ul><li>编译期属性语义 → <a href="pages/compile-time-attributes.html">编译期属性</a></li><li>降级后如何发射 C++ → <a href="pages/generator.html">生成器总览</a></li><li>常量表达式校验 → <a href="pages/type-check.html">类型检查与兼容</a></li></ul></div></body></html>