Skip to content

Commit

Permalink
Add TemplateCovariant attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-granados committed Feb 19, 2024
1 parent 1582a2d commit 21d2d55
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,5 @@ These are the available attributes and their corresponding PHPDoc annotations:
| [PropertyWrite](https://github.com/php-static-analysis/attributes/blob/main/doc/PropertyWrite.md) | `@property-write` |
| [Returns](https://github.com/php-static-analysis/attributes/blob/main/doc/Returns.md) | `@return` |
| [Template](https://github.com/php-static-analysis/attributes/blob/main/doc/Template.md) | `@template` |
| [TemplateCovariant](https://github.com/php-static-analysis/attributes/blob/main/doc/TemplateCovariant.md) | `@template-covariant` |
| [Type](https://github.com/php-static-analysis/attributes/blob/main/doc/Type.md) | `@var` `@return` |
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"require": {
"php": ">=8.0",
"ext-simplexml": "*",
"php-static-analysis/attributes": "^0.1.4 || dev-main",
"php-static-analysis/node-visitor": "^0.1.4 || dev-main",
"php-static-analysis/attributes": "^0.1.5 || dev-main",
"php-static-analysis/node-visitor": "^0.1.5 || dev-main",
"vimeo/psalm": "^5"
},
"require-dev": {
Expand Down
12 changes: 12 additions & 0 deletions tests/PropertyAttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ public function testClassPropertyAttribute(): void
$this->assertCount(0, $errors);
}

public function testInterfacePropertyAttribute(): void
{
$errors = $this->analyzeTestFile( '/data/Property/InterfacePropertyAttribute.php');
$this->assertCount(0, $errors);
}

public function testTraitPropertyAttribute(): void
{
$errors = $this->analyzeTestFile( '/data/Property/TraitPropertyAttribute.php');
$this->assertCount(0, $errors);
}

public function testInvalidClassPropertyAttribute(): void
{
$errors = $this->analyzeTestFile('/data/Property/InvalidClassPropertyAttribute.php');
Expand Down
12 changes: 12 additions & 0 deletions tests/PropertyReadAttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ public function testClassPropertyReadAttribute(): void
$this->assertCount(0, $errors);
}

public function testInterfacePropertyReadAttribute(): void
{
$errors = $this->analyzeTestFile( '/data/PropertyRead/InterfacePropertyReadAttribute.php');
$this->assertCount(0, $errors);
}

public function testTraitPropertyReadAttribute(): void
{
$errors = $this->analyzeTestFile( '/data/PropertyRead/TraitPropertyReadAttribute.php');
$this->assertCount(0, $errors);
}

public function testInvalidClassPropertyReadAttribute(): void
{
$errors = $this->analyzeTestFile('/data/PropertyRead/InvalidClassPropertyReadAttribute.php');
Expand Down
12 changes: 12 additions & 0 deletions tests/PropertyWriteAttributeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ public function testClassPropertyWriteAttribute(): void
$this->assertCount(0, $errors);
}

public function testInterfacePropertyWriteAttribute(): void
{
$errors = $this->analyzeTestFile( '/data/PropertyWrite/InterfacePropertyWriteAttribute.php');
$this->assertCount(0, $errors);
}

public function testTraitPropertyWriteAttribute(): void
{
$errors = $this->analyzeTestFile( '/data/PropertyWrite/TraitPropertyWriteAttribute.php');
$this->assertCount(0, $errors);
}

public function testInvalidClassPropertyWriteAttribute(): void
{
$errors = $this->analyzeTestFile('/data/PropertyWrite/InvalidClassPropertyWriteAttribute.php');
Expand Down
37 changes: 37 additions & 0 deletions tests/TemplateCovariantAttributeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace test\PhpStaticAnalysis\PsalmPlugin;

class TemplateCovariantAttributeTest extends BaseAttributeTestCase
{
public function testClassTemplateCovariantAttribute(): void
{
$errors = $this->analyzeTestFile('/data/TemplateCovariant/ClassTemplateCovariantAttribute.php');
$this->assertCount(0, $errors);
}

public function testInterfaceTemplateCovariantAttribute(): void
{
$errors = $this->analyzeTestFile('/data/TemplateCovariant/InterfaceTemplateCovariantAttribute.php');
$this->assertCount(0, $errors);
}

public function testTraitTemplateCovariantAttribute(): void
{
$errors = $this->analyzeTestFile('/data/TemplateCovariant/TraitTemplateCovariantAttribute.php');
$this->assertCount(0, $errors);
}

public function testInvalidClassTemplateCovariantAttribute(): void
{
$errors = $this->analyzeTestFile('/data/TemplateCovariant/InvalidClassTemplateCovariantAttribute.php');
$this->checkExpectedErrors($errors,[
'Empty @template-covariant tag in docblock for test\PhpStaticAnalysis\PsalmPlugin\data\TemplateCovariant\InvalidClassTemplateCovariantAttribute' => 10,
'Argument 1 of PhpStaticAnalysis\Attributes\TemplateCovariant::__construct expects string, but 0 provided' => 7,
'Argument 2 of PhpStaticAnalysis\Attributes\TemplateCovariant::__construct expects null|string, but 0 provided' => 9,
'Attribute TemplateCovariant cannot be used on a property' => 12,
]);
}
}
10 changes: 10 additions & 0 deletions tests/data/Property/InterfacePropertyAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\Property;

use PhpStaticAnalysis\Attributes\Property;

#[Property(name: 'string')]
interface InterfacePropertyAttribute
{
}
10 changes: 10 additions & 0 deletions tests/data/Property/TraitPropertyAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\Property;

use PhpStaticAnalysis\Attributes\Property;

#[Property(name: 'string')]
trait TraitPropertyAttribute
{
}
10 changes: 10 additions & 0 deletions tests/data/PropertyRead/InterfacePropertyReadAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\PropertyRead;

use PhpStaticAnalysis\Attributes\PropertyRead;

#[PropertyRead(name: 'string')]
interface InterfacePropertyReadAttribute
{
}
10 changes: 10 additions & 0 deletions tests/data/PropertyRead/TraitPropertyReadAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\PropertyRead;

use PhpStaticAnalysis\Attributes\PropertyRead;

#[PropertyRead(name: 'string')]
trait TraitPropertyReadAttribute
{
}
10 changes: 10 additions & 0 deletions tests/data/PropertyWrite/InterfacePropertyWriteAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\PropertyWrite;

use PhpStaticAnalysis\Attributes\PropertyWrite;

#[PropertyWrite(name: 'string')]
interface InterfacePropertyWriteAttribute
{
}
10 changes: 10 additions & 0 deletions tests/data/PropertyWrite/TraitPropertyWriteAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\PropertyWrite;

use PhpStaticAnalysis\Attributes\PropertyWrite;

#[PropertyWrite(name: 'string')]
trait TraitPropertyWriteAttribute
{
}
35 changes: 35 additions & 0 deletions tests/data/TemplateCovariant/ClassTemplateCovariantAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\TemplateCovariant;

use PhpStaticAnalysis\Attributes\Param;
use PhpStaticAnalysis\Attributes\Returns;
use PhpStaticAnalysis\Attributes\TemplateCovariant;
use PhpStaticAnalysis\Attributes\Type;

abstract class ClassTemplateCovariantAttribute
{
abstract public function getName() : string;
}
class ClassTemplateCovariantAttributeChild extends ClassTemplateCovariantAttribute
{
public function getName() : string { return "child"; }
}

#[TemplateCovariant('T')]
class Collection {
#[Type('array<int, T>')]
public array $list = [];
}

#[Param(collection: 'Collection<ClassTemplateCovariantAttribute>')]
function getNames(Collection $collection) : void {
foreach ($collection->list as $item) {
echo $item->getName();
}
}

#[Param(children: 'Collection<ClassTemplateCovariantAttributeChild>')]
function listChildNames(Collection $children) : void {
getNames($children);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\TemplateCovariant;

use PhpStaticAnalysis\Attributes\Returns;
use PhpStaticAnalysis\Attributes\TemplateCovariant;

#[TemplateCovariant('T')]
interface InterfaceTemplateCovariantAttribute
{
#[Returns('T')]
public function returnTemplateCovariant();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\TemplateCovariant;

use PhpStaticAnalysis\Attributes\TemplateCovariant;

#[TemplateCovariant(0)]
#[TemplateCovariant('')]
#[TemplateCovariant('T', 0)]
class InvalidClassTemplateCovariantAttribute
{
#[TemplateCovariant('T')]
public string $property = '';
}
18 changes: 18 additions & 0 deletions tests/data/TemplateCovariant/TraitTemplateCovariantAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace test\PhpStaticAnalysis\PsalmPlugin\data\TemplateCovariant;

use PhpStaticAnalysis\Attributes\Param;
use PhpStaticAnalysis\Attributes\Returns;
use PhpStaticAnalysis\Attributes\TemplateCovariant;

#[TemplateCovariant('T')]
trait TraitTemplateCovariantAttribute
{
#[Param(param: 'T')]
#[Returns('T')]
public function returnTemplateCovariant($param)
{
return $param;
}
}

0 comments on commit 21d2d55

Please sign in to comment.