Problem
#58 tracks public instance methods and Expr_MethodCall. examples/003-MiniWebApp/src/Router.php also needs:
Today lint reports ClassMethod / Expr_MethodCall under #58 / #463; runtime will need visibility dispatch once methods compile.
Goal
class Router {
private array $config;
public function __construct(array $config) { $this->config = $config; }
public function dispatch(string $method, string $route): void {
$this->renderHome(); // private call from public method
}
private function renderHome(): void { /* include templates */ }
}
VM + JIT + AOT: constructor runs on new; private methods callable only from same class; property reads/writes respect visibility.
Implementation hints
Compiler (lib/Compiler.php)
| Step |
Notes |
| Class vtable |
Per-class table: methodName → {visibility, funcId, isStatic} |
new |
Emit TYPE_NEW + TYPE_METHOD_CALL for __construct when present |
| Method call |
TYPE_METHOD_CALL checks visibility: caller class vs target method |
| Private calls |
Same-class fast path (no dynamic dispatch v1) |
VM (lib/VM.php)
- Object header: property bag + class id
__construct: run before returning object from new
- Illegal private call from outside class →
Error (match Zend message where feasible)
JIT (lib/JIT.php, lib/JIT/Builtin/Type/Object_.php)
- Monomorphic private calls within same class (Router → render*)
- Defer
protected cross-hierarchy to follow-up
AOT (lib/AOT/)
Lint (lib/Lint/UnsupportedRegistry.php)
Tests
test/compliance/cases/class_private_method.phpt
test/compliance/cases/class_constructor.phpt
- Extend
test/unit/MiniWebAppSkeletonTest.php when Router dispatches
Acceptance criteria
docker run --rm -v "$(pwd):/compiler" -w /compiler php-compiler:22.04-dev \
php bin/vm.php -r 'class C{private function h():string{return "ok";} public function go():string{return $this->h();}} echo (new C())->go();'
MiniWebApp may still fail on #54 includes until those close.
Verification (local / Docker only)
./script/ci-local.sh --filter class_visibility
No GitHub Actions required.
Dependencies
De-duplication
| Issue |
Relationship |
| #58 |
Public methods + external ->dispatch() calls |
| #101 / #144 |
Inheritance/traits — out of scope for MiniWebApp v1 |
| #169 |
Full PHP 8 types; #473 is MiniWebApp slice |
Links
Problem
#58 tracks public instance methods and
Expr_MethodCall.examples/003-MiniWebApp/src/Router.phpalso needs:renderHome,renderHello, …) called from publicdispatch()__constructwith assignment to$this->configprivate array $config(Language: Typed class properties for MiniWebApp Router (slice of #169) #473 slice of Language: Typed properties, union types, and readonly (PHP 8+) #169)protectedto v2)Today lint reports
ClassMethod/Expr_MethodCallunder #58 / #463; runtime will need visibility dispatch once methods compile.Goal
VM + JIT + AOT: constructor runs on
new; private methods callable only from same class; property reads/writes respect visibility.Implementation hints
Compiler (
lib/Compiler.php)methodName → {visibility, funcId, isStatic}newTYPE_NEW+TYPE_METHOD_CALLfor__constructwhen presentTYPE_METHOD_CALLchecks visibility: caller class vs target methodVM (
lib/VM.php)__construct: run before returning object fromnewError(match Zend message where feasible)JIT (
lib/JIT.php,lib/JIT/Builtin/Type/Object_.php)protectedcross-hierarchy to follow-upAOT (
lib/AOT/)includes[]must linkRouter.phpwith entry TULint (
lib/Lint/UnsupportedRegistry.php)Tests
test/compliance/cases/class_private_method.phpttest/compliance/cases/class_constructor.phpttest/unit/MiniWebAppSkeletonTest.phpwhen Router dispatchesAcceptance criteria
MiniWebApp may still fail on #54 includes until those close.
Verification (local / Docker only)
No GitHub Actions required.
Dependencies
private array $configDe-duplication
->dispatch()callsLinks
examples/003-MiniWebApp/src/Router.php