Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MethodExtensions class-name is case-insensitive #2562

Merged
merged 3 commits into from
Aug 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/Type/DynamicReturnTypeExtensionRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PHPStan\Reflection\BrokerAwareExtension;
use PHPStan\Reflection\ReflectionProvider;
use function array_merge;
use function strtolower;

class DynamicReturnTypeExtensionRegistry
{
Expand Down Expand Up @@ -46,7 +47,7 @@ public function getDynamicMethodReturnTypeExtensionsForClass(string $className):
if ($this->dynamicMethodReturnTypeExtensionsByClass === null) {
$byClass = [];
foreach ($this->dynamicMethodReturnTypeExtensions as $extension) {
$byClass[$extension->getClass()][] = $extension;
$byClass[strtolower($extension->getClass())][] = $extension;
}

$this->dynamicMethodReturnTypeExtensionsByClass = $byClass;
Expand All @@ -62,7 +63,7 @@ public function getDynamicStaticMethodReturnTypeExtensionsForClass(string $class
if ($this->dynamicStaticMethodReturnTypeExtensionsByClass === null) {
$byClass = [];
foreach ($this->dynamicStaticMethodReturnTypeExtensions as $extension) {
$byClass[$extension->getClass()][] = $extension;
$byClass[strtolower($extension->getClass())][] = $extension;
}

$this->dynamicStaticMethodReturnTypeExtensionsByClass = $byClass;
Expand All @@ -83,6 +84,7 @@ private function getDynamicExtensionsForType(array $extensions, string $classNam
$extensionsForClass = [[]];
$class = $this->reflectionProvider->getClass($className);
foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) {
$extensionClassName = strtolower($extensionClassName);
if (!isset($extensions[$extensionClassName])) {
continue;
}
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,7 @@ public function dataFileAsserts(): iterable
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7915.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9714.php');
}

/**
Expand Down
16 changes: 16 additions & 0 deletions tests/PHPStan/Analyser/data/bug-9714.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php declare(strict_types=1);

namespace Bug9714;

use function PHPStan\Testing\assertType;

class ExampleClass
{
public function exampleFunction(): void
{
$xml = new \SimpleXmlElement('');
$elements = $xml->xpath('//data');
assertType('array<SimpleXmlElement>', $elements);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test DynamicMethodReturnTypeExtension-case

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@

$returnType = $closure->call($newThis, new class {});
assertType('true', $returnType);

$staticallyBoundClosureCaseInsensitive = \closure::bind($closure, $newThis);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test DynamicStaticMethodReturnTypeExtension

assertType('Closure(object): true', $staticallyBoundClosureCaseInsensitive);
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/data/enum-from.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,10 @@ public function subsetToSuperset(FooIntegerEnumSubset $foo): void
assertType('EnumFrom\FooIntegerEnum::BAR', FooIntegerEnum::from($foo->value));
}

public function doCaseInsensitive(): void
{
assertType('1', FooInTeGerEnum::BAR->value);
assertType('null', FooInTeGerEnum::tryFrom(0));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ public function testRule(): void
'Dead catch - Exception is never thrown in the try block.',
532,
],
[
'Dead catch - Exception is never thrown in the try block.',
555,
],
]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,9 @@ public function dateTimeZoneDoesThrows(string $tz): void
new \DateTimeZone($tz);
}

public function dateTimeZoneDoesNotThrowCaseInsensitive(): void
{
new \DaTetImezOnE('UTC');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test DynamicStaticMethodThrowTypeExtension

}

}
32 changes: 32 additions & 0 deletions tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,35 @@ public function doBar(string $s)
}

}

class TestCaseInsensitiveClassNames
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there was no exisiting bug to fix for the throw-type-extension case.. but adding test coverage can not hurt

tests DynamicMethodThrowTypeExtension

{

public function doFoo(): void
{
try {
new \SimpleXmlElement('<?xml version="1.0" encoding="UTF-8"?><root></root>');
} catch (\Exception $e) {

}
}

public function doBar(): void
{
try {
new \SimpleXmlElement('foo');
} catch (\Exception $e) {

}
}

public function doBaz(string $string): void
{
try {
new \SimpleXmlElement($string);
} catch (\Exception $e) {

}
}

}