Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions src/PseudoTypes/ClassString.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace phpDocumentor\Reflection\PseudoTypes;

use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\PseudoType;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\Types\String_;
Expand All @@ -25,39 +24,33 @@
*/
final class ClassString extends String_ implements PseudoType
{
/** @var Fqsen|null */
private $fqsen;
/** @var Type|null */
private $genericType;

/**
* Initializes this representation of a class string with the given Fqsen.
*/
public function __construct(?Fqsen $fqsen = null)
public function __construct(?Type $genericType = null)
{
$this->fqsen = $fqsen;
$this->genericType = $genericType;
}

public function underlyingType(): Type
{
return new String_();
}

/**
* Returns the FQSEN associated with this object.
*/
public function getFqsen(): ?Fqsen
public function getGenericType(): ?Type
{
return $this->fqsen;
return $this->genericType;
}

/**
* Returns a rendered output of the Type as it would be used in a DocBlock.
*/
public function __toString(): string
{
if ($this->fqsen === null) {
if ($this->genericType === null) {
return 'class-string';
}

return 'class-string<' . (string) $this->fqsen . '>';
return 'class-string<' . (string) $this->genericType . '>';
}
}
23 changes: 8 additions & 15 deletions src/PseudoTypes/InterfaceString.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace phpDocumentor\Reflection\PseudoTypes;

use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\PseudoType;
use phpDocumentor\Reflection\Type;
use phpDocumentor\Reflection\Types\String_;
Expand All @@ -25,39 +24,33 @@
*/
final class InterfaceString extends String_ implements PseudoType
{
/** @var Fqsen|null */
private $fqsen;
/** @var Type|null */
private $genericType;

/**
* Initializes this representation of a class string with the given Fqsen.
*/
public function __construct(?Fqsen $fqsen = null)
public function __construct(?Type $genericType = null)
{
$this->fqsen = $fqsen;
$this->genericType = $genericType;
}

public function underlyingType(): Type
{
return new String_();
}

/**
* Returns the FQSEN associated with this object.
*/
public function getFqsen(): ?Fqsen
public function getGenericType(): ?Type
{
return $this->fqsen;
return $this->genericType;
}

/**
* Returns a rendered output of the Type as it would be used in a DocBlock.
*/
public function __toString(): string
{
if ($this->fqsen === null) {
if ($this->genericType === null) {
return 'interface-string';
}

return 'interface-string<' . (string) $this->fqsen . '>';
return 'interface-string<' . (string) $this->genericType . '>';
}
}
22 changes: 2 additions & 20 deletions src/TypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,28 +399,10 @@ private function createFromGeneric(GenericTypeNode $type, Context $context): Typ
return new NonEmptyArray(...$genericTypes);

case 'class-string':
$subType = $this->createType($type->genericTypes[0], $context);
if (!$subType instanceof Object_ || $subType->getFqsen() === null) {
throw new RuntimeException(
$subType . ' is not a class string'
);
}

return new ClassString(
$subType->getFqsen()
);
return new ClassString($this->createType($type->genericTypes[0], $context));

case 'interface-string':
$subType = $this->createType($type->genericTypes[0], $context);
if (!$subType instanceof Object_ || $subType->getFqsen() === null) {
throw new RuntimeException(
$subType . ' is not a class string'
);
}

return new InterfaceString(
$subType->getFqsen()
);
return new InterfaceString($this->createType($type->genericTypes[0], $context));

case 'list':
return new List_(
Expand Down
22 changes: 18 additions & 4 deletions tests/unit/PseudoTypes/ClassStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace phpDocumentor\Reflection\PseudoTypes;

use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Object_;
use PHPUnit\Framework\TestCase;

/**
Expand All @@ -25,19 +27,31 @@ class ClassStringTest extends TestCase
* @dataProvider provideClassStrings
* @covers ::__toString
*/
public function testClassStringStringifyCorrectly(ClassString $array, string $expectedString): void
public function testClassStringStringifyCorrectly(ClassString $type, string $expectedString): void
{
$this->assertSame($expectedString, (string) $array);
$this->assertSame($expectedString, (string) $type);
}

/**
* @return mixed[]
* @return array<string, array{ClassString, string}>
*/
public function provideClassStrings(): array
{
return [
'generic class string' => [new ClassString(), 'class-string'],
'typed class string' => [new ClassString(new Fqsen('\Foo\Bar')), 'class-string<\Foo\Bar>'],
'typed class string' => [
new ClassString(new Object_(new Fqsen('\Foo\Bar'))),
'class-string<\Foo\Bar>',
],
'more than one class' => [
new ClassString(
new Compound([
new Object_(new Fqsen('\Foo\Bar')),
new Object_(new Fqsen('\Foo\Barrr')),
])
),
'class-string<\Foo\Bar|\Foo\Barrr>',
],
];
}
}
22 changes: 18 additions & 4 deletions tests/unit/PseudoTypes/InterfaceStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
namespace phpDocumentor\Reflection\PseudoTypes;

use phpDocumentor\Reflection\Fqsen;
use phpDocumentor\Reflection\Types\Compound;
use phpDocumentor\Reflection\Types\Object_;
use PHPUnit\Framework\TestCase;

/**
Expand All @@ -25,19 +27,31 @@ class InterfaceStringTest extends TestCase
* @dataProvider provideInterfaceStrings
* @covers ::__toString
*/
public function testInterfaceStringStringifyCorrectly(InterfaceString $array, string $expectedString): void
public function testInterfaceStringStringifyCorrectly(InterfaceString $type, string $expectedString): void
{
$this->assertSame($expectedString, (string) $array);
$this->assertSame($expectedString, (string) $type);
}

/**
* @return mixed[]
* @return array<string, array{InterfaceString, string}>
*/
public function provideInterfaceStrings(): array
{
return [
'generic interface string' => [new InterfaceString(), 'interface-string'],
'typed interface string' => [new InterfaceString(new Fqsen('\Foo\Bar')), 'interface-string<\Foo\Bar>'],
'typed interface string' => [
new InterfaceString(new Object_(new Fqsen('\Foo\Bar'))),
'interface-string<\Foo\Bar>',
],
'more than one class' => [
new InterfaceString(
new Compound([
new Object_(new Fqsen('\Foo\Bar')),
new Object_(new Fqsen('\Foo\Barrr')),
])
),
'interface-string<\Foo\Bar|\Foo\Barrr>',
],
];
}
}
104 changes: 25 additions & 79 deletions tests/unit/TypeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,54 +112,6 @@ public function testResolvingKeywords(string $keyword, string $expectedClass): v
$this->assertInstanceOf($expectedClass, $resolvedType);
}

/**
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Object_
* @uses \phpDocumentor\Reflection\Types\String_
*
* @covers ::__construct
* @covers ::resolve
* @covers ::createType
*
* @dataProvider provideClassStrings
*/
public function testResolvingClassStrings(string $classString, bool $throwsException): void
{
$fixture = new TypeResolver();

if ($throwsException) {
$this->expectException(RuntimeException::class);
}

$resolvedType = $fixture->resolve($classString, new Context(''));

$this->assertInstanceOf(ClassString::class, $resolvedType);
}

/**
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Object_
* @uses \phpDocumentor\Reflection\Types\String_
*
* @covers ::__construct
* @covers ::resolve
* @covers ::createType
*
* @dataProvider provideInterfaceStrings
*/
public function testResolvingInterfaceStrings(string $interfaceString, bool $throwsException): void
{
$fixture = new TypeResolver();

if ($throwsException) {
$this->expectException(RuntimeException::class);
}

$resolvedType = $fixture->resolve($interfaceString, new Context(''));

$this->assertInstanceOf(InterfaceString::class, $resolvedType);
}

/**
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Object_
Expand Down Expand Up @@ -811,34 +763,6 @@ public function provideKeywords(): array
];
}

/**
* Returns a list of class string types and whether they throw an exception.
*
* @return (string|bool)[][]
*/
public function provideClassStrings(): array
{
return [
['class-string<\phpDocumentor\Reflection>', false],
['class-string<\phpDocumentor\Reflection\DocBlock>', false],
['class-string<string>', true],
];
}

/**
* Returns a list of interface string types and whether they throw an exception.
*
* @return (string|bool)[][]
*/
public function provideInterfaceStrings(): array
{
return [
['interface-string<\phpDocumentor\Reflection>', false],
['interface-string<\phpDocumentor\Reflection\DocBlock>', false],
['interface-string<string>', true],
];
}

/**
* Provides a list of FQSENs to test the resolution patterns with.
*
Expand Down Expand Up @@ -1122,15 +1046,37 @@ public function genericsProvider(): array
],
[
'class-string',
new ClassString(null),
new ClassString(),
],
[
'class-string<Foo>',
new ClassString(new Fqsen('\\phpDocumentor\\Foo')),
new ClassString(new Object_(new Fqsen('\\phpDocumentor\\Foo'))),
],
[
'class-string<Foo|Bar>',
new ClassString(
new Compound([
new Object_(new Fqsen('\\phpDocumentor\\Foo')),
new Object_(new Fqsen('\\phpDocumentor\\Bar')),
])
),
],
[
'interface-string',
new InterfaceString(),
],
[
'interface-string<Foo>',
new InterfaceString(new Fqsen('\\phpDocumentor\\Foo')),
new InterfaceString(new Object_(new Fqsen('\\phpDocumentor\\Foo'))),
],
[
'interface-string<Foo|Bar>',
new InterfaceString(
new Compound([
new Object_(new Fqsen('\\phpDocumentor\\Foo')),
new Object_(new Fqsen('\\phpDocumentor\\Bar')),
])
),
],
[
'List<Foo>',
Expand Down