Skip to content

Commit

Permalink
Do not prefix built-in PHP classes. Fix #79
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianHenryIE committed Dec 6, 2023
1 parent d26e040 commit 1bd20b7
Show file tree
Hide file tree
Showing 2 changed files with 381 additions and 0 deletions.
319 changes: 319 additions & 0 deletions src/ChangeEnumerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ 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]);
}

$discoveredClasses = array_filter(
array_keys($this->discoveredClasses),
Expand Down Expand Up @@ -241,4 +244,320 @@ protected function addDiscoveredNamespaceChange(string $namespace): void

$this->discoveredNamespaces[$namespace] = $this->namespacePrefix . '\\'. $namespace;
}

/**
* Get a list of PHP built-in classes 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.
*
* NB: This list is not exhaustive. Any unloaded PHP extensions are not included.
*
* @see https://github.com/BrianHenryIE/strauss/issues/79
*
* ```
* array_filter(
* get_declared_classes(),
* function(string $className): bool {
* $reflector = new \ReflectionClass($className);
* return empty($reflector->getFileName());
* }
* );
* ```
*
* @return string[]
*/
protected function getBuiltInClassnames(): 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',
],
'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' => [
'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' => [
'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' => [
],
'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',
]
]
)
);
}
}
62 changes: 62 additions & 0 deletions tests/Issues/StraussIssue79Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
/**
* JsonException core PHP class, polyfilled by Symfony, incorrectly replaced
*
*
*
* @see https://github.com/BrianHenryIE/strauss/issues/79
*/

namespace BrianHenryIE\Strauss\Tests\Issues;

use BrianHenryIE\Strauss\Console\Commands\Compose;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* @package BrianHenryIE\Strauss\Tests\Issues
* @coversNothing
*/
class StraussIssue79Test extends \BrianHenryIE\Strauss\Tests\Integration\Util\IntegrationTestCase
{

/**
*/
public function test_namespace_keyword_on_opening_line()
{

$composerJsonString = <<<'EOD'
{
"name": "issue/79",
"require": {
"json-mapper/json-mapper": "2.20.0"
},
"extra": {
"strauss": {
"namespace_prefix": "BrianHenryIE\\Issue79\\",
"classmap_prefix": "BH_Strauss_Issue79_"
}
}
}
EOD;

chdir($this->testsWorkingDir);

file_put_contents($this->testsWorkingDir . '/composer.json', $composerJsonString);

exec('composer install');

$inputInterfaceMock = $this->createMock(InputInterface::class);
$outputInterfaceMock = $this->createMock(OutputInterface::class);

$strauss = new Compose();

$result = $strauss->run($inputInterfaceMock, $outputInterfaceMock);

self::assertEquals(0, $result);

$php_string = file_get_contents($this->testsWorkingDir . '/vendor-prefixed/json-mapper/json-mapper/src/JsonMapper.php');
self::assertStringNotContainsString('throw new \BH_Strauss_Issue79_JsonException(json_last_error_msg()', $php_string);
self::assertStringContainsString('throw new \JsonException(json_last_error_msg(), \json_last_error());', $php_string);
}
}

0 comments on commit 1bd20b7

Please sign in to comment.