diff --git a/src/Preprocessor.php b/src/Preprocessor.php index 95783251..6e342245 100644 --- a/src/Preprocessor.php +++ b/src/Preprocessor.php @@ -695,7 +695,14 @@ class Preprocessor extends CompilerBase $flags = Modifiers::PUBLIC; } if (isset($this->symbolDeclInFile[$fullClassNameLower])) { - $this->fatalError($class, "Duplicate class `{$fullClassName}`"); + // AOT-tolerant duplicate handling: PHP autoloading only ever loads + // one declaration of a given FQN at runtime, so cross-file + // duplicates (common in frameworks like ThinkPHP, where several + // packages ship an identical copy of the same class) are not a + // fatal error. Keep the first declaration and skip the rest. + $this->warning($class, "Duplicate class `{$fullClassName}` (also declared in {$this->symbolDeclInFile[$fullClassNameLower]}); keeping the first declaration."); + $this->resetClass(); + return ''; } $this->classDef = new ClassDef($this->class, $flags, $this->namespace); @@ -1505,7 +1512,10 @@ class Preprocessor extends CompilerBase } if (isset($this->symbolDeclInFile[$interfaceNameLower])) { - $this->fatalError($v, "Duplicate interface `{$interfaceName}`"); + // Same AOT-tolerant handling as classes: keep the first declaration + // of a duplicated interface FQN and skip the rest. + $this->warning($v, "Duplicate interface `{$interfaceName}` (also declared in {$this->symbolDeclInFile[$interfaceNameLower]}); keeping the first declaration."); + return; } $this->symbolDeclInFile[$interfaceNameLower] = $this->file;