Skip to content

Commit

Permalink
Add ODM annotatoin/attribute based check (#41)
Browse files Browse the repository at this point in the history
* add document annotation based test

* add ODM annotation/attribute detection
  • Loading branch information
TomasVotruba authored Aug 18, 2024
1 parent f0de67e commit 3f36b2d
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 30 deletions.
17 changes: 17 additions & 0 deletions composer-dependency-analyser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

use ShipMonk\ComposerDependencyAnalyser\Config\Configuration;
use ShipMonk\ComposerDependencyAnalyser\Config\ErrorType;

$config = new Configuration();

return $config
->addPathToScan(__DIR__ . '/src', false)
->addPathToScan(__DIR__ . '/tests', false)
// test fixture
->ignoreErrorsOnPath(
__DIR__ . '/tests/EntityClassResolver/Fixture/Anything/SomeAttributeDocument.php',
[ErrorType::UNKNOWN_CLASS]
);
71 changes: 50 additions & 21 deletions src/PhpParser/NodeVisitor/EntityClassNameCollectingNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use PhpParser\NodeVisitorAbstract;
use Webmozart\Assert\Assert;

final class EntityClassNameCollectingNodeVisitor extends NodeVisitorAbstract
{
/**
* @var string[]
*/
private const ODM_SUFFIXES = ['Document', 'EmbeddedDocument'];

/**
* @var string[]
*/
private const ORM_SUFFIXES = ['Entity', 'Embeddable'];

/**
* @var string[]
*/
Expand All @@ -28,13 +39,7 @@ public function enterNode(Node $node): ?Node
return null;
}

// dummy check for entity namespace + odm
if (array_intersect(['Entity', 'Entities', 'Document'], $node->namespacedName->getParts())) {
$this->entityClassNames[] = $node->namespacedName->toString();
return null;
}

if ($this->hasEntityDocBlock($node) || $this->hasEntityAttribute($node)) {
if ($this->hasEntityAnnotation($node) || $this->hasEntityAttribute($node)) {
$this->entityClassNames[] = $node->namespacedName->toString();
return null;
}
Expand All @@ -53,41 +58,65 @@ public function getEntityClassNames(): array
return $uniqueEntityClassNames;
}

private function hasEntityDocBlock(Class_ $class): bool
/**
* @param string[] $suffixes
*/
private function hasDocBlockSuffixes(Class_ $class, array $suffixes): bool
{
Assert::allString($suffixes);

$docComment = $class->getDocComment();
if ($docComment instanceof Doc) {
// dummy check
if (! str_contains($docComment->getText(), '@')) {
return false;
}

if (str_contains($docComment->getText(), 'Entity')) {
return true;
}

if (str_contains($docComment->getText(), 'Embeddable')) {
return true;
foreach ($suffixes as $suffix) {
if (str_contains($docComment->getText(), $suffix)) {
return true;
}
}
}

return false;
}

private function hasEntityAttribute(Class_ $class): bool
/**
* @param string[] $suffixes
*/
private function hasAttributeSuffixes(Class_ $class, array $suffixes): bool
{
Assert::allString($suffixes);

foreach ($class->attrGroups as $attrGroup) {
foreach ($attrGroup->attrs as $attr) {
if (str_ends_with($attr->name->toString(), 'Entity')) {
return true;
}

if (str_ends_with($attr->name->toString(), 'Embeddable')) {
return true;
foreach ($suffixes as $suffix) {
if (str_ends_with($attr->name->toString(), $suffix)) {
return true;
}
}
}
}

return false;
}

private function hasEntityAnnotation(Class_ $class): bool
{
if ($this->hasDocBlockSuffixes($class, self::ODM_SUFFIXES)) {
return true;
}

return $this->hasDocBlockSuffixes($class, self::ORM_SUFFIXES);
}

private function hasEntityAttribute(Class_ $class): bool
{
if ($this->hasAttributeSuffixes($class, self::ODM_SUFFIXES)) {
return true;
}

return $this->hasAttributeSuffixes($class, self::ORM_SUFFIXES);
}
}
20 changes: 18 additions & 2 deletions tests/EntityClassResolver/EntityClassResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

use Rector\SwissKnife\EntityClassResolver;
use Rector\SwissKnife\Tests\AbstractTestCase;
use Rector\SwissKnife\Tests\EntityClassResolver\Fixture\Anything\SomeAttributeDocument;
use Rector\SwissKnife\Tests\EntityClassResolver\Fixture\Anything\SomeDocument;
use Rector\SwissKnife\Tests\EntityClassResolver\Fixture\Entity\SomeEntity;

final class EntityClassResolverTest extends AbstractTestCase
Expand All @@ -21,12 +23,26 @@ protected function setUp(): void

public function test(): void
{
$entityClasses = $this->entityClassResolver->resolve([__DIR__ . '/Fixture'], static function (): void {
});
$entityClasses = $this->entityClassResolver->resolve(
[__DIR__ . '/Fixture/Entity', __DIR__ . '/Fixture/config'],
static function (): void {
}
);

$this->assertSame(
['App\Some\Entity\Conference', 'App\Some\Entity\Project', 'App\Some\Entity\Talk', SomeEntity::class],
$entityClasses
);
}

public function testODMDocument(): void
{
$documentClasses = $this->entityClassResolver->resolve(
[__DIR__ . '/Fixture/Anything'],
static function (): void {
}
);

$this->assertSame([SomeAttributeDocument::class, SomeDocument::class], $documentClasses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Rector\SwissKnife\Tests\EntityClassResolver\Fixture\Anything;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

#[MongoDB\Document]
class SomeAttributeDocument
{
}
12 changes: 12 additions & 0 deletions tests/EntityClassResolver/Fixture/Anything/SomeDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Rector\SwissKnife\Tests\EntityClassResolver\Fixture\Anything;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;

/**
* @MongoDB\EmbeddedDocument()
*/
class SomeDocument
{
}
5 changes: 5 additions & 0 deletions tests/EntityClassResolver/Fixture/Entity/SomeEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

namespace Rector\SwissKnife\Tests\EntityClassResolver\Fixture\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
*/
class SomeEntity
{
}
7 changes: 0 additions & 7 deletions tests/EntityClassResolver/Fixture/SomeClass.php

This file was deleted.

0 comments on commit 3f36b2d

Please sign in to comment.