From 74cbff14654577de8b6ade81fc2f3a65328eda78 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 15 Sep 2026 16:40:13 +0800 Subject: [PATCH] feat(compiler): replace hardcoded autoloader path with dynamic resolution - Replace direct require of TYPEPHP_ROOT_PATH . '/vendor/autoload.php' with resolveComposerAutoloader() function - Add new resolveComposerAutoloader() function to locate Composer autoloader from multiple candidate paths - Support both source checkout and packaged SDK environments by checking TYPEPHP_ROOT_PATH and PHP_HOME - Implement fallback mechanism to search for vendor/autoload.php in different locations - Add detailed error reporting when autoloader is not found with specific search paths - Include installation instructions in error output when dependencies are missing - Exit with error code 1 when autoloader cannot be located --- src/compiler.php | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/compiler.php b/src/compiler.php index 649a6742..145135d7 100644 --- a/src/compiler.php +++ b/src/compiler.php @@ -32,7 +32,7 @@ function main(int $argc, array $argv): void // in bin/bootstrap.php. The AOT compiler starts here directly and therefore // must load the dependencies packaged alongside tpc itself. if (!defined('TYPEPHP_PHP_SCRIPT_ENTRY')) { - require_once TYPEPHP_ROOT_PATH . '/vendor/autoload.php'; + require_once resolveComposerAutoloader(); } $completionStatus = CompletionCommand::execute($argv); @@ -136,6 +136,43 @@ function main(int $argc, array $argv): void } } +/** + * Locate the Composer autoloader that ships with the compiler. + * + * A source checkout and a Unix-like package keep it below TYPEPHP_ROOT_PATH, + * while a packaged SDK extracts it below PHP_HOME. + */ +function resolveComposerAutoloader(): string +{ + $candidates = []; + $roots = [TYPEPHP_ROOT_PATH, getenv('PHP_HOME') ?: null]; + foreach ($roots as $root) { + if (!is_string($root) || $root === '') { + continue; + } + $candidate = rtrim($root, '/\\') . '/vendor/autoload.php'; + if (!in_array($candidate, $candidates, true)) { + $candidates[] = $candidate; + } + } + + foreach ($candidates as $candidate) { + if (is_file($candidate)) { + return $candidate; + } + } + + fwrite(STDERR, "Unable to find the Composer autoloader (vendor/autoload.php).\n"); + fwrite(STDERR, "Searched in:\n"); + foreach ($candidates as $candidate) { + fwrite(STDERR, " - {$candidate}\n"); + } + fwrite(STDERR, "\nInstall the TypePHP dependencies with Composer first:\n"); + fwrite(STDERR, " cd " . TYPEPHP_ROOT_PATH . " && composer install\n"); + fwrite(STDERR, "Or point PHP_HOME at a TypePHP installation that already contains vendor/autoload.php.\n"); + exit(1); +} + function shouldCompileNativeSourceProject(array $argv): bool { foreach (array_slice($argv, 1) as $argument) {