From 3772aedf868fad9b2e23333094415023cb5170d4 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 12 Nov 2026 15:59:37 +0000 Subject: [PATCH] =?UTF-8?q?fix(parser):=20::class=20=E5=9C=A8=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=9C=9F=E5=B1=95=E5=BC=80=E5=BD=93=E5=89=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E7=A9=BA=E9=97=B4=E4=B8=8E=20use=20=E5=88=AB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 未限定 ClassName::class 先前仅在 findFullClassNameByNamespace 返回 ok=true 时采用 FQCN,类未加载时会固化为短名。与 parseStaticCall 一致, 编译期始终采用返回的候选全名,符合 PHP 不要求类存在且不 autoload 的语义。 Co-authored-by: selden --- parser/ident_parser.go | 4 +- tests/php/class_const_compile_time_test.php | 71 +++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 tests/php/class_const_compile_time_test.php diff --git a/parser/ident_parser.go b/parser/ident_parser.go index 3bb4035a..8a3feb7f 100644 --- a/parser/ident_parser.go +++ b/parser/ident_parser.go @@ -150,9 +150,11 @@ func (p *IdentParser) Parse() (data.GetValue, data.Control) { } // 处理 ::class 语法(须优先于「关键字作方法名」,避免 class 被当成静态成员) + // PHP 编译期解析:类不必存在,也不触发 autoload;findFullClassNameByNamespace + // 在 ok=false 时仍返回当前命名空间 / use 展开后的候选 FQCN,必须采用。 if p.checkPositionIs(0, token.SCOPE_RESOLUTION) && p.checkPositionIs(1, token.CLASS) { className := name - if full, ok := p.findFullClassNameByNamespace(className); ok { + if full, _ := p.findFullClassNameByNamespace(className); full != "" { className = full } p.next() // 跳过 :: diff --git a/tests/php/class_const_compile_time_test.php b/tests/php/class_const_compile_time_test.php new file mode 100644 index 00000000..102853c3 --- /dev/null +++ b/tests/php/class_const_compile_time_test.php @@ -0,0 +1,71 @@ +