From a48ad695d96dc65db6b70163cb9a89887d511100 Mon Sep 17 00:00:00 2001 From: Brian Henry Date: Tue, 26 Mar 2024 11:22:10 -0700 Subject: [PATCH] Add missing built-in PHP interfaces for exclusion --- .gitignore | 1 + scripts/getbuiltinphp.php | 85 +++++ src/ChangeEnumerator.php | 738 +++++++++++++++++++++++--------------- 3 files changed, 535 insertions(+), 289 deletions(-) create mode 100644 scripts/getbuiltinphp.php diff --git a/.gitignore b/.gitignore index c2ad22e6..b466efef 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ scratch pcov.sh xdebug.sh 7.4linux.sh +scripts/builtins.php diff --git a/scripts/getbuiltinphp.php b/scripts/getbuiltinphp.php new file mode 100644 index 00000000..97691961 --- /dev/null +++ b/scripts/getbuiltinphp.php @@ -0,0 +1,85 @@ + [], + 'interfaces' => [], + 'traits' => [], + ]; +} + +$classes = array_filter( + get_declared_classes(), + function (string $className): bool { + $reflector = new \ReflectionClass($className); + return empty($reflector->getFileName()); + } +); + +$interfaces = array_filter( + get_declared_interfaces(), + function (string $interfaceName): bool { + $reflector = new \ReflectionClass($interfaceName); + return empty($reflector->getFileName()); + } +); + +$traits = array_filter( + get_declared_traits(), + function (string $traitName): bool { + $reflector = new \ReflectionClass($traitName); + return empty($reflector->getFileName()); + } +); + + +// Remove classes, interfaces, traits that are built-in in this PHP version from future versions. +foreach ($builtins as $phpVersion => $builtinsArray) { + if (version_compare($phpVersion, $currentPhpVersion, '>')) { + $builtins[$phpVersion]['classes'] = array_diff($builtinsArray['classes'], $classes); + $builtins[$phpVersion]['interfaces'] = array_diff($builtinsArray['interfaces'], $interfaces); + $builtins[$phpVersion]['traits'] = array_diff($builtinsArray['traits'], $traits); + } +} + +// Remove from this PHP version's built-ins list classes, interfaces, traits that exist in older versions. +foreach ($builtins as $phpVersion => $builtinsArray) { + if (version_compare($phpVersion, $currentPhpVersion, '<')) { + $classes = array_diff($classes, $builtinsArray['classes']); + $interfaces = array_diff($interfaces, $builtinsArray['interfaces']); + $traits = array_diff($traits, $builtinsArray['traits']); + } +} + +$builtins[$currentPhpVersion]['classes'] = array_unique(array_merge($builtins[$currentPhpVersion]['classes'], $classes)); +$builtins[$currentPhpVersion]['interfaces'] = array_unique(array_merge($builtins[$currentPhpVersion]['interfaces'], $interfaces)); +$builtins[$currentPhpVersion]['traits'] = array_unique(array_merge($builtins[$currentPhpVersion]['traits'], $traits)); + +foreach ($builtins as $phpVersion => $builtinsArray) { + asort($builtins[$currentPhpVersion]['classes']); + asort($builtins[$currentPhpVersion]['interfaces']); + asort($builtins[$currentPhpVersion]['traits']); +} + + +$outputText = '\s/', '', $outputText); + +file_put_contents($outputFile, $outputText); diff --git a/src/ChangeEnumerator.php b/src/ChangeEnumerator.php index b3c4c555..b4b0faca 100644 --- a/src/ChangeEnumerator.php +++ b/src/ChangeEnumerator.php @@ -86,8 +86,8 @@ public function getDiscoveredNamespaces(?string $namespacePrefix = ''): array public function getDiscoveredClasses(?string $classmapPrefix = ''): array { unset($this->discoveredClasses['ReturnTypeWillChange']); - foreach ($this->getBuiltInClassnames() as $builtInClass) { - unset($this->discoveredClasses[$builtInClass]); + foreach ($this->getBuiltIns() as $builtIn) { + unset($this->discoveredClasses[$builtIn]); } $discoveredClasses = array_filter( @@ -247,7 +247,7 @@ protected function addDiscoveredNamespaceChange(string $namespace): void } /** - * Get a list of PHP built-in classes so they are not prefixed. + * Get a list of PHP built-in classes etc. so they are not prefixed. * * Polyfilled classes were being prefixed, but the polyfills are only active when the PHP version is below X, * so calls to those prefixed polyfilled classnames would fail on newer PHP versions. @@ -268,297 +268,457 @@ protected function addDiscoveredNamespaceChange(string $namespace): void * * @return string[] */ - protected function getBuiltInClassnames(): array + protected function getBuiltIns(): array { - return array_merge( - ...array_values( - [ - '7.4' => [ - 'AppendIterator', - 'ArgumentCountError', - 'ArithmeticError', - 'ArrayIterator', - 'ArrayObject', - 'AssertionError', - 'BadFunctionCallException', - 'BadMethodCallException', - 'CURLFile', - 'CachingIterator', - 'CallbackFilterIterator', - 'ClosedGeneratorException', - 'Closure', - 'Collator', - 'CompileError', - 'DOMAttr', - 'DOMCdataSection', - 'DOMCharacterData', - 'DOMComment', - 'DOMConfiguration', - 'DOMDocument', - 'DOMDocumentFragment', - 'DOMDocumentType', - 'DOMDomError', - 'DOMElement', - 'DOMEntity', - 'DOMEntityReference', - 'DOMErrorHandler', - 'DOMException', - 'DOMImplementation', - 'DOMImplementationList', - 'DOMImplementationSource', - 'DOMLocator', - 'DOMNameList', - 'DOMNameSpaceNode', - 'DOMNamedNodeMap', - 'DOMNode', - 'DOMNodeList', - 'DOMNotation', - 'DOMProcessingInstruction', - 'DOMStringExtend', - 'DOMStringList', - 'DOMText', - 'DOMTypeinfo', - 'DOMUserDataHandler', - 'DOMXPath', - 'DateInterval', - 'DatePeriod', - 'DateTime', - 'DateTimeImmutable', - 'DateTimeZone', - 'Directory', - 'DirectoryIterator', - 'DivisionByZeroError', - 'DomainException', - 'EmptyIterator', - 'Error', - 'ErrorException', - 'Exception', - 'FFI', - 'FFI\CData', - 'FFI\CType', - 'FFI\Exception', - 'FFI\ParserException', - 'FilesystemIterator', - 'FilterIterator', - 'GMP', - 'Generator', - 'GlobIterator', - 'HashContext', - 'InfiniteIterator', - 'IntlBreakIterator', - 'IntlCalendar', - 'IntlChar', - 'IntlCodePointBreakIterator', - 'IntlDateFormatter', - 'IntlException', - 'IntlGregorianCalendar', - 'IntlIterator', - 'IntlPartsIterator', - 'IntlRuleBasedBreakIterator', - 'IntlTimeZone', - 'InvalidArgumentException', - 'IteratorIterator', - 'JsonException', - 'LengthException', - 'LibXMLError', - 'LimitIterator', - 'Locale', - 'LogicException', - 'MessageFormatter', - 'MultipleIterator', - 'NoRewindIterator', - 'Normalizer', - 'NumberFormatter', - 'OutOfBoundsException', - 'OutOfRangeException', - 'OverflowException', - 'PDO', - 'PDOException', - 'PDORow', - 'PDOStatement', - 'ParentIterator', - 'ParseError', - 'Phar', - 'PharData', - 'PharException', - 'PharFileInfo', - 'RangeException', - 'RecursiveArrayIterator', - 'RecursiveCachingIterator', - 'RecursiveCallbackFilterIterator', - 'RecursiveDirectoryIterator', - 'RecursiveFilterIterator', - 'RecursiveIteratorIterator', - 'RecursiveRegexIterator', - 'RecursiveTreeIterator', - 'Reflection', - 'ReflectionClass', - 'ReflectionClassConstant', - 'ReflectionException', - 'ReflectionExtension', - 'ReflectionFunction', - 'ReflectionFunctionAbstract', - 'ReflectionGenerator', - 'ReflectionMethod', - 'ReflectionNamedType', - 'ReflectionObject', - 'ReflectionParameter', - 'ReflectionProperty', - 'ReflectionReference', - 'ReflectionType', - 'ReflectionZendExtension', - 'RegexIterator', - 'ResourceBundle', - 'RuntimeException', - 'SQLite3', - 'SQLite3Result', - 'SQLite3Stmt', - 'SessionHandler', - 'SimpleXMLElement', - 'SimpleXMLIterator', - 'SoapClient', - 'SoapFault', - 'SoapHeader', - 'SoapParam', - 'SoapServer', - 'SoapVar', - 'SodiumException', - 'SplDoublyLinkedList', - 'SplFileInfo', - 'SplFileObject', - 'SplFixedArray', - 'SplHeap', - 'SplMaxHeap', - 'SplMinHeap', - 'SplObjectStorage', - 'SplPriorityQueue', - 'SplQueue', - 'SplStack', - 'SplTempFileObject', - 'Spoofchecker', - 'Transliterator', - 'TypeError', - 'UConverter', - 'UnderflowException', - 'UnexpectedValueException', - 'WeakReference', - 'XMLReader', - 'XMLWriter', - 'XSLTProcessor', - 'ZipArchive', - '__PHP_Incomplete_Class', - 'finfo', - 'mysqli', - 'mysqli_driver', - 'mysqli_result', - 'mysqli_sql_exception', - 'mysqli_stmt', - 'mysqli_warning', - 'php_user_filter', - 'stdClass', - 'tidy', - 'tidyNode', + $builtins = [ + '7.4' => + [ + 'classes' => + [ + 'AppendIterator', + 'ArgumentCountError', + 'ArithmeticError', + 'ArrayIterator', + 'ArrayObject', + 'AssertionError', + 'BadFunctionCallException', + 'BadMethodCallException', + 'CURLFile', + 'CachingIterator', + 'CallbackFilterIterator', + 'ClosedGeneratorException', + 'Closure', + 'Collator', + 'CompileError', + 'DOMAttr', + 'DOMCdataSection', + 'DOMCharacterData', + 'DOMComment', + 'DOMConfiguration', + 'DOMDocument', + 'DOMDocumentFragment', + 'DOMDocumentType', + 'DOMDomError', + 'DOMElement', + 'DOMEntity', + 'DOMEntityReference', + 'DOMErrorHandler', + 'DOMException', + 'DOMImplementation', + 'DOMImplementationList', + 'DOMImplementationSource', + 'DOMLocator', + 'DOMNameList', + 'DOMNameSpaceNode', + 'DOMNamedNodeMap', + 'DOMNode', + 'DOMNodeList', + 'DOMNotation', + 'DOMProcessingInstruction', + 'DOMStringExtend', + 'DOMStringList', + 'DOMText', + 'DOMTypeinfo', + 'DOMUserDataHandler', + 'DOMXPath', + 'DateInterval', + 'DatePeriod', + 'DateTime', + 'DateTimeImmutable', + 'DateTimeZone', + 'Directory', + 'DirectoryIterator', + 'DivisionByZeroError', + 'DomainException', + 'EmptyIterator', + 'Error', + 'ErrorException', + 'Exception', + 'FFI', + 'FFI\\CData', + 'FFI\\CType', + 'FFI\\Exception', + 'FFI\\ParserException', + 'FilesystemIterator', + 'FilterIterator', + 'GMP', + 'Generator', + 'GlobIterator', + 'HashContext', + 'InfiniteIterator', + 'IntlBreakIterator', + 'IntlCalendar', + 'IntlChar', + 'IntlCodePointBreakIterator', + 'IntlDateFormatter', + 'IntlException', + 'IntlGregorianCalendar', + 'IntlIterator', + 'IntlPartsIterator', + 'IntlRuleBasedBreakIterator', + 'IntlTimeZone', + 'InvalidArgumentException', + 'IteratorIterator', + 'JsonException', + 'LengthException', + 'LibXMLError', + 'LimitIterator', + 'Locale', + 'LogicException', + 'MessageFormatter', + 'MultipleIterator', + 'NoRewindIterator', + 'Normalizer', + 'NumberFormatter', + 'OutOfBoundsException', + 'OutOfRangeException', + 'OverflowException', + 'PDO', + 'PDOException', + 'PDORow', + 'PDOStatement', + 'ParentIterator', + 'ParseError', + 'Phar', + 'PharData', + 'PharException', + 'PharFileInfo', + 'RangeException', + 'RecursiveArrayIterator', + 'RecursiveCachingIterator', + 'RecursiveCallbackFilterIterator', + 'RecursiveDirectoryIterator', + 'RecursiveFilterIterator', + 'RecursiveIteratorIterator', + 'RecursiveRegexIterator', + 'RecursiveTreeIterator', + 'Reflection', + 'ReflectionClass', + 'ReflectionClassConstant', + 'ReflectionException', + 'ReflectionExtension', + 'ReflectionFunction', + 'ReflectionFunctionAbstract', + 'ReflectionGenerator', + 'ReflectionMethod', + 'ReflectionNamedType', + 'ReflectionObject', + 'ReflectionParameter', + 'ReflectionProperty', + 'ReflectionReference', + 'ReflectionType', + 'ReflectionZendExtension', + 'RegexIterator', + 'ResourceBundle', + 'RuntimeException', + 'SQLite3', + 'SQLite3Result', + 'SQLite3Stmt', + 'SessionHandler', + 'SimpleXMLElement', + 'SimpleXMLIterator', + 'SoapClient', + 'SoapFault', + 'SoapHeader', + 'SoapParam', + 'SoapServer', + 'SoapVar', + 'SodiumException', + 'SplDoublyLinkedList', + 'SplFileInfo', + 'SplFileObject', + 'SplFixedArray', + 'SplHeap', + 'SplMaxHeap', + 'SplMinHeap', + 'SplObjectStorage', + 'SplPriorityQueue', + 'SplQueue', + 'SplStack', + 'SplTempFileObject', + 'Spoofchecker', + 'Transliterator', + 'TypeError', + 'UConverter', + 'UnderflowException', + 'UnexpectedValueException', + 'WeakReference', + 'XMLReader', + 'XMLWriter', + 'XSLTProcessor', + 'ZipArchive', + '__PHP_Incomplete_Class', + 'finfo', + 'mysqli', + 'mysqli_driver', + 'mysqli_result', + 'mysqli_sql_exception', + 'mysqli_stmt', + 'mysqli_warning', + 'php_user_filter', + 'stdClass', + 'tidy', + 'tidyNode', + ], + 'interfaces' => + [ + 'ArrayAccess', + 'Countable', + 'DateTimeInterface', + 'Iterator', + 'IteratorAggregate', + 'JsonSerializable', + 'OuterIterator', + 'RecursiveIterator', + 'Reflector', + 'SeekableIterator', + 'Serializable', + 'SessionHandlerInterface', + 'SessionIdInterface', + 'SessionUpdateTimestampHandlerInterface', + 'SplObserver', + 'SplSubject', + 'Throwable', + 'Traversable', + ], + 'traits' => + [ + ], ], - '8.0' => [ - 'AddressInfo', - 'Attribute', - 'CurlHandle', - 'CurlMultiHandle', - 'CurlShareHandle', - 'DeflateContext', - 'GdImage', - 'InflateContext', - 'InternalIterator', - 'OpenSSLAsymmetricKey', - 'OpenSSLCertificate', - 'OpenSSLCertificateSigningRequest', - 'PhpToken', - 'ReflectionAttribute', - 'ReflectionUnionType', - 'Shmop', - 'Socket', - 'SysvMessageQueue', - 'SysvSemaphore', - 'SysvSharedMemory', - 'UnhandledMatchError', - 'ValueError', - 'WeakMap', - 'XMLParser', + '8.1' => + [ + 'classes' => + [ + 'AddressInfo', + 'Attribute', + 'CURLStringFile', + 'CurlHandle', + 'CurlMultiHandle', + 'CurlShareHandle', + 'DeflateContext', + 'FTP\\Connection', + 'Fiber', + 'FiberError', + 'GdFont', + 'GdImage', + 'InflateContext', + 'InternalIterator', + 'IntlDatePatternGenerator', + 'LDAP\\Connection', + 'LDAP\\Result', + 'LDAP\\ResultEntry', + 'OpenSSLAsymmetricKey', + 'OpenSSLCertificate', + 'OpenSSLCertificateSigningRequest', + 'PSpell\\Config', + 'PSpell\\Dictionary', + 'PgSql\\Connection', + 'PgSql\\Lob', + 'PgSql\\Result', + 'PhpToken', + 'ReflectionAttribute', + 'ReflectionEnum', + 'ReflectionEnumBackedCase', + 'ReflectionEnumUnitCase', + 'ReflectionFiber', + 'ReflectionIntersectionType', + 'ReflectionUnionType', + 'ReturnTypeWillChange', + 'Shmop', + 'Socket', + 'SysvMessageQueue', + 'SysvSemaphore', + 'SysvSharedMemory', + 'UnhandledMatchError', + 'ValueError', + 'WeakMap', + 'XMLParser', + ], + 'interfaces' => + [ + 'BackedEnum', + 'DOMChildNode', + 'DOMParentNode', + 'Stringable', + 'UnitEnum', + ], + 'traits' => + [ + ], ], - '8.1' => [ - 'CURLStringFile', - 'FTP\Connection', - 'Fiber', - 'FiberError', - 'GdFont', - 'IntlDatePatternGenerator', - 'LDAP\Connection', - 'LDAP\Result', - 'LDAP\ResultEntry', - 'PSpell\Config', - 'PSpell\Dictionary', - 'PgSql\Connection', - 'PgSql\Lob', - 'PgSql\Result', - 'ReflectionEnum', - 'ReflectionEnumBackedCase', - 'ReflectionEnumUnitCase', - 'ReflectionFiber', - 'ReflectionIntersectionType', - 'ReturnTypeWillChange', + '8.2' => + [ + 'classes' => + [ + 'AddressInfo', + 'AllowDynamicProperties', + 'Attribute', + 'CURLStringFile', + 'CurlHandle', + 'CurlMultiHandle', + 'CurlShareHandle', + 'DeflateContext', + 'FTP\\Connection', + 'Fiber', + 'FiberError', + 'GdFont', + 'GdImage', + 'InflateContext', + 'InternalIterator', + 'IntlDatePatternGenerator', + 'LDAP\\Connection', + 'LDAP\\Result', + 'LDAP\\ResultEntry', + 'OpenSSLAsymmetricKey', + 'OpenSSLCertificate', + 'OpenSSLCertificateSigningRequest', + 'PSpell\\Config', + 'PSpell\\Dictionary', + 'PgSql\\Connection', + 'PgSql\\Lob', + 'PgSql\\Result', + 'PhpToken', + 'Random\\BrokenRandomEngineError', + 'Random\\Engine\\Mt19937', + 'Random\\Engine\\PcgOneseq128XslRr64', + 'Random\\Engine\\Secure', + 'Random\\Engine\\Xoshiro256StarStar', + 'Random\\RandomError', + 'Random\\RandomException', + 'Random\\Randomizer', + 'ReflectionAttribute', + 'ReflectionEnum', + 'ReflectionEnumBackedCase', + 'ReflectionEnumUnitCase', + 'ReflectionFiber', + 'ReflectionIntersectionType', + 'ReflectionUnionType', + 'ReturnTypeWillChange', + 'SensitiveParameter', + 'SensitiveParameterValue', + 'Shmop', + 'Socket', + 'SysvMessageQueue', + 'SysvSemaphore', + 'SysvSharedMemory', + 'UnhandledMatchError', + 'ValueError', + 'WeakMap', + 'XMLParser', + ], + 'interfaces' => + [ + 'BackedEnum', + 'DOMChildNode', + 'DOMParentNode', + 'Random\\CryptoSafeEngine', + 'Random\\Engine', + 'Stringable', + 'UnitEnum', + ], + 'traits' => + [ + ], ], - '8.2' => [ - 'AllowDynamicProperties', - 'Random\BrokenRandomEngineError', - 'Random\Engine\Mt19937', - 'Random\Engine\PcgOneseq128XslRr64', - 'Random\Engine\Secure', - 'Random\Engine\Xoshiro256StarStar', - 'Random\RandomError', - 'Random\RandomException', - 'Random\Randomizer', - 'SensitiveParameter', - 'SensitiveParameterValue', + '8.3' => + [ + 'classes' => + [ + 'AddressInfo', + 'AllowDynamicProperties', + 'Attribute', + 'CURLStringFile', + 'CurlHandle', + 'CurlMultiHandle', + 'CurlShareHandle', + 'DateError', + 'DateException', + 'DateInvalidOperationException', + 'DateInvalidTimeZoneException', + 'DateMalformedIntervalStringException', + 'DateMalformedPeriodStringException', + 'DateMalformedStringException', + 'DateObjectError', + 'DateRangeError', + 'DeflateContext', + 'FTP\\Connection', + 'Fiber', + 'FiberError', + 'GdFont', + 'GdImage', + 'InflateContext', + 'InternalIterator', + 'IntlDatePatternGenerator', + 'LDAP\\Connection', + 'LDAP\\Result', + 'LDAP\\ResultEntry', + 'OpenSSLAsymmetricKey', + 'OpenSSLCertificate', + 'OpenSSLCertificateSigningRequest', + 'Override', + 'PSpell\\Config', + 'PSpell\\Dictionary', + 'PgSql\\Connection', + 'PgSql\\Lob', + 'PgSql\\Result', + 'PhpToken', + 'Random\\BrokenRandomEngineError', + 'Random\\Engine\\Mt19937', + 'Random\\Engine\\PcgOneseq128XslRr64', + 'Random\\Engine\\Secure', + 'Random\\Engine\\Xoshiro256StarStar', + 'Random\\IntervalBoundary', + 'Random\\RandomError', + 'Random\\RandomException', + 'Random\\Randomizer', + 'ReflectionAttribute', + 'ReflectionEnum', + 'ReflectionEnumBackedCase', + 'ReflectionEnumUnitCase', + 'ReflectionFiber', + 'ReflectionIntersectionType', + 'ReflectionUnionType', + 'ReturnTypeWillChange', + 'SQLite3Exception', + 'SensitiveParameter', + 'SensitiveParameterValue', + 'Shmop', + 'Socket', + 'SysvMessageQueue', + 'SysvSemaphore', + 'SysvSharedMemory', + 'UnhandledMatchError', + 'ValueError', + 'WeakMap', + 'XMLParser', + ], + 'interfaces' => + [ + 'BackedEnum', + 'DOMChildNode', + 'DOMParentNode', + 'Random\\CryptoSafeEngine', + 'Random\\Engine', + 'Stringable', + 'UnitEnum', + ], + 'traits' => + [ + ], ], - '8.3' => [ - ], - '8.4' => [ - 'DOM\Document', - 'DOM\HTMLDocument', - 'DOM\XMLDocument', - 'DateError', - 'DateException', - 'DateInvalidOperationException', - 'DateInvalidTimeZoneException', - 'DateMalformedIntervalStringException', - 'DateMalformedPeriodStringException', - 'DateMalformedStringException', - 'DateObjectError', - 'DateRangeError', - 'Override', - 'Random\IntervalBoundary', - 'SQLite3Exception', - 'dom\attr', - 'dom\cdatasection', - 'dom\characterdata', - 'dom\comment', - 'dom\documentfragment', - 'dom\documenttype', - 'dom\domexception', - 'dom\element', - 'dom\entity', - 'dom\entityreference', - 'dom\namednodemap', - 'dom\namespacenode', - 'dom\node', - 'dom\nodelist', - 'dom\notation', - 'dom\processinginstruction', - 'dom\text', - 'dom\xpath', - ] - ] - ) + ]; + + $flatArray = array(); + array_walk_recursive( + $builtins, + function ($array) use (&$flatArray) { + if (is_array($array)) { + $flatArray = array_merge($flatArray, array_values($array)); + } else { + $flatArray[] = $array; + } + } ); + return $flatArray; } }