Skip to content

Added support for mixin #94

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions lib/Bridge/Phpactor/Docblock.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
use Phpactor\Docblock\DocblockType;
use Phpactor\Docblock\DocblockTypes;
use Phpactor\Docblock\Tag\MethodTag;
use Phpactor\Docblock\Tag\MixinTag;
use Phpactor\WorseReflection\Bridge\TolerantParser\Reflection\ReflectionInterface;
use Phpactor\WorseReflection\Core\Deprecation;
use Phpactor\WorseReflection\Core\DocBlock\DocBlock as CoreDocblock;
use Phpactor\Docblock\Docblock as PhpactorDocblock;
use Phpactor\WorseReflection\Core\DocBlock\DocBlockVars;
use Phpactor\WorseReflection\Core\Name;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionMethodCollection;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionPropertyCollection;
use Phpactor\WorseReflection\Core\Reflection\ReflectionClassLike;
Expand Down Expand Up @@ -113,6 +115,16 @@ public function vars(): DocBlockVars
return new DocBlockVars($vars);
}

/**
* @return Name[]
*/
public function mixins(): array
{
return array_map(function (MixinTag $tag) {
return Name::fromString($tag->fqn());
}, iterator_to_array($this->docblock->tags()->byName('mixin')));
}

public function inherits(): bool
{
return 0 !== $this->docblock->tags()->byName('inheritDoc')->count();
Expand Down
26 changes: 26 additions & 0 deletions lib/Bridge/Phpactor/MemberProvider/MixinMemberProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Phpactor\WorseReflection\Bridge\Phpactor\MemberProvider;

use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionMemberCollection;
use Phpactor\WorseReflection\Core\ServiceLocator;
use Phpactor\WorseReflection\Core\Virtual\Collection\VirtualReflectionMemberCollection;
use Phpactor\WorseReflection\Core\Virtual\ReflectionMemberProvider;
use Phpactor\WorseReflection\Core\Reflection\ReflectionClassLike;
use Phpactor\WorseReflection\Core\Reflection\ReflectionMember;

class MixinMemberProvider implements ReflectionMemberProvider
{
public function provideMembers(ServiceLocator $locator, ReflectionClassLike $class): ReflectionMemberCollection
{
$collection = VirtualReflectionMemberCollection::fromMembers([]);
foreach ($class->docblock()->mixins() as $name) {
$fqn = $class->scope()->resolveLocalName($name);
$mixinClass = $locator->reflector()->reflectClass($fqn);

$collection = $collection->merge($mixinClass->members());
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

note this is wrong. this will add the actual members to the class and make no distinction between the "real" methods and the fake ones.

we will need to convert the actual member to a VirtualMember.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

also handle class-not-found

}

return $collection;
}
}
6 changes: 6 additions & 0 deletions lib/Core/DocBlock/DocBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Phpactor\WorseReflection\Core\DocBlock;

use Phpactor\WorseReflection\Core\Deprecation;
use Phpactor\WorseReflection\Core\Name;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionMethodCollection;
use Phpactor\WorseReflection\Core\Reflection\Collection\ReflectionPropertyCollection;
use Phpactor\WorseReflection\Core\Reflection\ReflectionClassLike;
Expand Down Expand Up @@ -33,4 +34,9 @@ public function vars(): DocBlockVars;
public function inherits(): bool;

public function deprecation(): Deprecation;

/**
* @return Name[]
*/
public function mixins(): array;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Phpactor\WorseReflection\Tests\Integration\Bridge\TolerantParser\Reflection;

use Generator;
use Phpactor\WorseReflection\Core\Visibility;
use Phpactor\WorseReflection\Tests\Integration\IntegrationTestCase;
use Phpactor\WorseReflection\Core\ClassName;
Expand Down Expand Up @@ -771,7 +772,10 @@ public function testVirtualMethods(string $source, string $class, \Closure $asse
}


public function provideVirtualMethods()
/**
* @return Generator<mixed>
*/
public function provideVirtualMethods(): Generator
{
yield 'virtual methods' => [
<<<'EOT'
Expand Down Expand Up @@ -1154,4 +1158,46 @@ function (ReflectionClass $class) {
}
];
}

/**
* @dataProvider provideMixins
*/
public function testMixins(string $source, string $class, \Closure $assertion)
{
$class = $this->createReflector($source)->reflectClassLike(ClassName::fromString($class));
$assertion($class);
}

/**
* @return Generator<mixed>
*/
public function provideMixins(): Generator
{
yield 'mixin' => [
<<<'EOT'
<?php

class Class2
{
public function foobar(): void
{
}
}

/**
* @mixin Class2
*/
class Class1
{
}

EOT
,
'Class1',
function (ReflectionClass $class) {
$this->assertEquals(1, $class->methods()->count());
$this->assertEquals('foobar', $class->methods()->first()->name());
}
];
}
}
2 changes: 2 additions & 0 deletions tests/Integration/IntegrationTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Phpactor\TestUtils\Workspace;
use Phpactor\WorseReflection\Bridge\Phpactor\MemberProvider\DocblockMemberProvider;
use Phpactor\WorseReflection\Bridge\Phpactor\MemberProvider\MixinMemberProvider;
use Phpactor\WorseReflection\Core\SourceCodeLocator\StubSourceLocator;
use Phpactor\WorseReflection\Reflector;
use PHPUnit\Framework\TestCase;
Expand All @@ -29,6 +30,7 @@ public function createReflector(string $source): Reflector
return ReflectorBuilder::create()
->addSource($source)
->addMemberProvider(new DocblockMemberProvider())
->addMemberProvider(new MixinMemberProvider())
->withLogger($this->logger())->build();
}

Expand Down
10 changes: 10 additions & 0 deletions tests/Unit/Bridge/Phpactor/DocblockTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHPUnit\Framework\TestCase;
use Phpactor\WorseReflection\Bridge\Phpactor\DocblockFactory;
use Phpactor\WorseReflection\Core\DocBlock\DocBlock;
use Phpactor\WorseReflection\Core\Name;

class DocblockTest extends TestCase
{
Expand Down Expand Up @@ -68,6 +69,15 @@ public function testInherits()
$this->assertTrue($docblock->inherits());
}

public function testMixins(): void
{
$docblock = $this->create('/** @mixin Foobar */');
$mixins = $docblock->mixins();
self::assertCount(1, $mixins);
$mixin = reset($mixins);
self::assertInstanceOf(Name::class, $mixin);
}

public function testDeprecated(): void
{
$docblock = $this->create('/** Hello */');
Expand Down