Skip to content

Commit d825b52

Browse files
author
Guillaume Chehami
committed
fix phpstan Call to an undefined method PhpParser\ParserFactory::createForVersion()
1 parent 21ccea5 commit d825b52

28 files changed

Lines changed: 120 additions & 40 deletions

src/FileExtractor/PHPFileExtractor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ final class PHPFileExtractor implements FileExtractor
3333
public function getSourceLocations(SplFileInfo $file, SourceCollection $collection): void
3434
{
3535
$path = $file->getRelativePath();
36-
$parser = (new ParserFactory())->createForVersion(PhpVersion::fromString('8.1'));
36+
$parser = (new ParserFactory())->createForNewestSupportedVersion();
3737
$traverser = new NodeTraverser();
3838
foreach ($this->visitors as $v) {
3939
$v->init($collection, $file);

src/Visitor/Php/Symfony/FormTrait.php

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,103 @@
1212
namespace Translation\Extractor\Visitor\Php\Symfony;
1313

1414
use PhpParser\Node;
15-
use PhpParser\Node\Stmt;
15+
use PhpParser\Node\Stmt\Class_;
1616

1717
trait FormTrait
1818
{
1919
private bool $isFormType = false;
20+
private array $classMap = [];
21+
private array $hierarchyCache = [];
22+
private array $symfonyInterface = [
23+
'Symfony\Component\Form\FormTypeInterface',
24+
'FormTypeInterface',
25+
];
2026

21-
/**
22-
* Check if this node is a form type.
23-
*/
24-
private function isFormType(Node $node): bool
27+
protected function registerClass(Class_ $node): void
2528
{
26-
// Check if the class implements FormTypeInterface
27-
if ($node instanceof Stmt\Class_) {
28-
$this->isFormType = \in_array(
29-
'Symfony\Component\Form\FormTypeInterface',
30-
array_map(fn ($interface) => $interface->toString(), $node->implements ?? [])
31-
);
29+
if (!isset($node->name)) {
30+
return;
31+
}
32+
33+
$fqcn = $node->name->toString();
34+
35+
$this->classMap[$fqcn] = [
36+
'extends' => $node->extends?->toString(),
37+
'implements' => array_map(
38+
fn($i) => $i->toString(),
39+
$node->implements
40+
),
41+
];
42+
}
43+
44+
protected function resolveHierarchy(
45+
string $class,
46+
array &$visited = []
47+
): array {
48+
if (isset($this->hierarchyCache[$class])) {
49+
return $this->hierarchyCache[$class];
50+
}
51+
52+
if (isset($visited[$class])) {
53+
return [
54+
'extends' => [],
55+
'implements' => [],
56+
];
57+
}
58+
59+
$visited[$class] = true;
60+
61+
$data = $this->classMap[$class] ?? null;
62+
63+
if (!$data) {
64+
return [
65+
'extends' => [],
66+
'implements' => [],
67+
];
68+
}
69+
70+
$hierarchy = [
71+
'extends' => [],
72+
'implements' => $data['implements'],
73+
];
74+
75+
$parent = $data['extends'];
76+
77+
if ($parent) {
78+
$hierarchy['extends'][$parent] =
79+
$this->resolveHierarchy($parent, $visited);
80+
}
81+
82+
$this->hierarchyCache[$class] = $hierarchy;
83+
84+
return $hierarchy;
85+
}
86+
87+
protected function containsInterface(
88+
array $hierarchy
89+
): bool {
90+
91+
foreach ($this->symfonyInterface as $interface) {
92+
if (in_array($interface, $hierarchy['implements'], true)) {
93+
return true;
94+
}
95+
}
96+
97+
foreach ($hierarchy['extends'] as $parentHierarchy) {
98+
if ($this->containsInterface($parentHierarchy)) {
99+
return true;
100+
}
101+
}
102+
103+
return false;
104+
}
105+
106+
protected function isFormType(Node $node): bool
107+
{
108+
if ($node instanceof Class_) {
109+
$this->registerClass($node);
110+
$hierarchy = $this->resolveHierarchy($node->name->toString());
111+
$this->isFormType = $this->containsInterface($hierarchy);
32112
}
33113

34114
return $this->isFormType;

tests/Resources/Github/Issue_109.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Translation\Extractor\Tests\Resources\Github;
44
use Translation\Extractor\Annotation\Ignore;
55

6-
class MustNotBeIgnoredType
6+
class MustNotBeIgnoredType implements FormTypeInterface
77
{
88
public function buildForm(FormBuilderInterface $builder, array $options)
99
{

tests/Resources/Github/Issue_111.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Translation\Extractor\Annotation\Ignore;
66

7-
class Issue111Type
7+
class Issue111Type implements FormTypeInterface
88
{
99
public function buildForm(FormBuilderInterface $builder, array $options)
1010
{

tests/Resources/Github/Issue_62.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use Symfony\Component\Form\AbstractType;
44
use Translation\Extractor\Annotation\Ignore;
55

6-
class EmptyValueType extends AbstractType
6+
class EmptyValueType implements FormTypeInterface
77
{
88
public function buildForm(FormBuilderInterface $builder, array $options)
99
{

tests/Resources/Github/Issue_78.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use Symfony\Component\Form\AbstractType;
44
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
55

6-
class EmptyValueType extends AbstractType
6+
class EmptyValueType implements FormTypeInterface
77
{
88
public function buildForm(FormBuilderInterface $builder, array $options)
99
{

tests/Resources/Github/Issue_80b.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use Symfony\Component\Form\AbstractType;
44

5-
class PlaceholderAsBooleanType extends AbstractType
5+
class PlaceholderAsBooleanType implements FormTypeInterface
66
{
77
public function buildForm(FormBuilderInterface $builder, array $options)
88
{

tests/Resources/Github/issue_82.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Translation\Extractor\Tests\Resources\Github;
44

5-
class GlobalTranslationDomainType
5+
class GlobalTranslationDomainType implements FormTypeInterface
66
{
77
public function buildForm(FormBuilderInterface $builder, array $options)
88
{

tests/Resources/Github/issue_96.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Translation\Extractor\Tests\Resources\Github;
44

5-
class GlobalTranslationDomainWithPlaceholderType
5+
class GlobalTranslationDomainWithPlaceholderType implements FormTypeInterface
66
{
77
public function buildForm(FormBuilderInterface $builder, array $options)
88
{

tests/Resources/Php/Symfony/ChainedChoiceType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Translation\Extractor\Tests\Resources\Php\Symfony;
44

5-
class ChainedChoiceType
5+
class ChainedChoiceType implements FormTypeInterface
66
{
77
public function buildForm(FormBuilderInterface $builder, array $options)
88
{

0 commit comments

Comments
 (0)