Skip to content

Commit

Permalink
Refactor doctrine/annotation from dynamic to own static-reflection pa…
Browse files Browse the repository at this point in the history
…rser (#5974)

* remove doctrine/annotations

* Refactor doctrine/annotation parser to static reflection with phpdoc-parser

* remove doctirne-annotation-parser-syncer

* remove annotation stubs

* use nodes

* almost there

* [ci-review] Rector Rectify

* skip temporary

* phpstan: remove fixed messages

Co-authored-by: kaizen-ci <info@kaizen-ci.org>
  • Loading branch information
TomasVotruba and kaizen-ci authored Apr 4, 2021
1 parent d2e4c0a commit b2412ad
Show file tree
Hide file tree
Showing 213 changed files with 2,683 additions and 6,703 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/packages_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ jobs:
matrix:
package_name:
- rector-nette
- rector-symfony
# skip until packages use new static doctrine annotation parser
# rector-symfony
- rector-laravel
- rector-phpunit
- rector-cakephp
Expand Down
7 changes: 0 additions & 7 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@
// $container->get(Type::class) → instance of "Type"
override(\Psr\Container\ContainerInterface::get(0), type(0));

// $propertyPhpDocInfo->getByType(Type::class) → instance of "Type"|null
# inspired at: /~https://github.com/Ocramius/phpunit/blob/2894f1e5eb2cd88708fdba608718e5b6a07391aa/.phpstorm.meta.php#L4-L9
override(
\Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo::getByType(0),
map(['@&null'])
);

// PhpStorm 2019.1 - add argument autocomplete
// https://blog.jetbrains.com/phpstorm/2019/02/new-phpstorm-meta-php-features/
expectedArguments(
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@
"composer/semver": "^3.2",
"composer/xdebug-handler": "^1.4",
"danielstjules/stringy": "^3.1",
"doctrine/annotations": "^1.12",
"doctrine/inflector": "^2.0",
"jean85/pretty-package-versions": "^1.5.1|^2.0.1",
"nette/caching": "^3.1",
"nette/robot-loader": "^3.4",
"nette/utils": "^3.2",
"nikic/php-parser": "^4.10.4",
"phpstan/phpstan": "^0.12.82",
"phpstan/phpdoc-parser": "^0.5.2",
"phpstan/phpstan": "^0.12.83",
"phpstan/phpdoc-parser": "^0.5.4",
"phpstan/phpstan-phpunit": "^0.12.18",
"rector/rector-symfony": "^0.10.0",
"rector/rector-nette": "^0.10.0",
Expand Down Expand Up @@ -103,6 +102,7 @@
},
"classmap": [
"stubs/Annotations",
"stubs/Nette",
"rules-tests/Autodiscovery/Rector/FileNode/MoveInterfacesToContractNamespaceDirectoryRector/Expected",
"rules-tests/Autodiscovery/Rector/FileNode/MoveServicesBySuffixToDirectoryRector/Expected",
"rules-tests/CodingStyle/Rector/Namespace_/ImportFullyQualifiedNamesRector/Source",
Expand Down
1 change: 1 addition & 0 deletions config/services-packages.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
__DIR__ . '/../packages/BetterPhpDocParser/Attributes/Attribute',
__DIR__ . '/../packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php',
__DIR__ . '/../packages/Testing/PHPUnit',
__DIR__ . '/../packages/BetterPhpDocParser/PhpDoc',

// used in PHPStan
__DIR__ . '/../packages/NodeTypeResolver/Reflection/BetterReflection/RectorBetterReflectionSourceLocatorFactory.php',
Expand Down
7 changes: 4 additions & 3 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
declare(strict_types=1);

use Composer\Semver\VersionParser;
use Doctrine\Common\Annotations\Reader;
use Doctrine\Inflector\Inflector;
use Doctrine\Inflector\Rules\English\InflectorFactory;
use Nette\Caching\Cache;
Expand All @@ -20,13 +19,14 @@
use PHPStan\File\FileHelper;
use PHPStan\PhpDoc\TypeNodeResolver;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\Reflection\ReflectionProvider;
use Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser;
use Rector\BetterPhpDocParser\PhpDocParser\BetterTypeParser;
use Rector\Caching\Cache\NetteCacheFactory;
use Rector\Core\Console\ConsoleApplication;
use Rector\Core\PhpParser\Parser\NikicPhpParserFactory;
use Rector\Core\PhpParser\Parser\PhpParserLexerFactory;
use Rector\DoctrineAnnotationGenerated\ConstantPreservingAnnotationReader;
use Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory;
use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocator\IntermediateSourceLocator;
use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider;
Expand Down Expand Up @@ -115,7 +115,6 @@
// phpdoc parser
$services->set(\PHPStan\PhpDocParser\Lexer\Lexer::class);
$services->alias(PhpDocParser::class, BetterPhpDocParser::class);
$services->alias(Reader::class, ConstantPreservingAnnotationReader::class);

// cache
$services->set(DependencyResolver::class)
Expand All @@ -129,6 +128,8 @@
// type resolving
$services->set(IntermediateSourceLocator::class);

$services->alias(TypeParser::class, BetterTypeParser::class);

// PHPStan services
$services->set(ReflectionProvider::class)
->factory([service(PHPStanServicesFactory::class), 'createReflectionProvider']);
Expand Down
18 changes: 11 additions & 7 deletions docs/how_to_work_with_doc_block_and_comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ var_dump($paramTypes);

## How to Get Class Annotation?

Each class annotation has their own object to work with. E.g. to work with Doctrine entities:
Doctrine class annotations are annotations based on [`doctrine/annotations`](/~https://github.com/doctrine/annotations/) package. They are classes that have `@annotation`. Most common are Doctrine entity, column, one to many etc., but also Symfony route or Symfony validation annotations.

Let's look how to work one for Doctrine entity:

```php
use Doctrine\ORM\Mapping as ORM;
Expand All @@ -80,17 +82,19 @@ class UserEntity
}
```

You can use `EntityTagValueNode` object:

```php
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Doctrine\Class_\EntityTagValueNode;

/** @var PhpDocInfo $phpDocInfo */
$entityTagValueNode = $phpDocInfo->getByType(EntityTagValueNode::class);
if (! $entityTagValueNode instanceof EntityTagValueNode) {
$entityTagValueNode = $phpDocInfo->getByAnnotationClass('Doctrine\ORM\Mapping\Entity');
if (! $entityTagValueNode instanceof DoctrineAnnotationTagValueNode) {
return null;
}

var_dump($entityTagValueNode->getShortName()); // "@ORM\Entity"
$annotationClass = $entityTagValueNode->getAnnotationClass();
var_dump($annotationClass); // "Doctrine\ORM\Mapping\Entity"

$values = $entityTagValueNode->getValues();
var_dump($values); // []
```
7 changes: 3 additions & 4 deletions ecs.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,13 @@
'*TypeResolver*',
'*NameResolver*',
'*Mapper*',
// allowed @required
__DIR__ . '/packages/StaticTypeMapper/Naming/NameScopeFactory.php',
__DIR__ . '/packages/NodeTypeResolver/NodeTypeResolver.php',
__DIR__ . '/packages/BetterPhpDocParser/PhpDocNodeFactory/AbstractPhpDocNodeFactory.php',
__DIR__ . '/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/PlainValueParser.php',
],

# generated from /vendor
__DIR__ . '/packages/DoctrineAnnotationGenerated/ConstantPreservingDocParser.php',
__DIR__ . '/packages/DoctrineAnnotationGenerated/ConstantPreservingAnnotationReader.php',

UnaryOperatorSpacesFixer::class,

// buggy with specific markdown snippet file in docs/rules_overview.md
Expand All @@ -87,6 +85,7 @@
PhpUnitStrictFixer::class => [
__DIR__ . '/packages-tests/BetterPhpDocParser/PhpDocInfo/PhpDocInfo/PhpDocInfoTest.php',
__DIR__ . '/tests/PhpParser/Node/NodeFactoryTest.php',
__DIR__ . '/packages-tests/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/StaticDoctrineAnnotationParserTest.php',
'*TypeResolverTest.php',
],
]);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** @template T as int */
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** @template T of int */
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/**
* @var (callable(mixed $value, string $typeName):mixed)[]
*/

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser;

use Iterator;
use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory;
use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser;
use Rector\Core\HttpKernel\RectorKernel;
use Symplify\PackageBuilder\Testing\AbstractKernelTestCase;

final class ArrayParserTest extends AbstractKernelTestCase
{
/**
* @var ArrayParser
*/
private $arrayParser;

/**
* @var TokenIteratorFactory
*/
private $tokenIteratorFactory;

protected function setUp(): void
{
$this->bootKernel(RectorKernel::class);

$this->arrayParser = $this->getService(ArrayParser::class);
$this->tokenIteratorFactory = $this->getService(TokenIteratorFactory::class);
}

/**
* @dataProvider provideData()
* @param array<string, string>|string[] $expectedArray
*/
public function test(string $docContent, array $expectedArray): void
{
$betterTokenIterator = $this->tokenIteratorFactory->create($docContent);

$array = $this->arrayParser->parserArray($betterTokenIterator);
$this->assertSame($expectedArray, $array);
}

public function provideData(): Iterator
{
yield ['{key: "value"}', [
'key' => '"value"',
]];

yield ['{"key": "value"}', [
'"key"' => '"value"',
]];

yield ['{"value", "value2"}', ['"value"', '"value2"']];
}
}
Loading

0 comments on commit b2412ad

Please sign in to comment.