mirror of
https://github.com/rectorphp/rector.git
synced 2024-07-01 07:03:32 +00:00
[NodeTypeResolver] Unwrap standalone usage, not working and ContainerFactory is better approach ATM
This commit is contained in:
parent
1c1b548cb2
commit
7d989cd58f
10
.travis.yml
10
.travis.yml
|
@ -3,7 +3,7 @@ language: php
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- php: 7.1
|
- php: 7.1
|
||||||
env: STATIC_ANALYSIS=true RUN_RECTOR=true MONOREPO_SPLIT=true
|
env: STATIC_ANALYSIS=true RUN_RECTOR=true
|
||||||
#- php: 7.1
|
#- php: 7.1
|
||||||
# env: COMPOSER_FLAGS="--prefer-lowest"
|
# env: COMPOSER_FLAGS="--prefer-lowest"
|
||||||
- php: 7.2
|
- php: 7.2
|
||||||
|
@ -30,14 +30,6 @@ script:
|
||||||
bin/rector generate-rector-overview >> rector-overview.md
|
bin/rector generate-rector-overview >> rector-overview.md
|
||||||
fi
|
fi
|
||||||
|
|
||||||
after_script:
|
|
||||||
# split monorepo to packages - only on merge to master + publish prefixed version
|
|
||||||
- |
|
|
||||||
if [[ $TRAVIS_EVENT_TYPE == "push" && $MONOREPO_SPLIT == true && $TRAVIS_BRANCH == "master" ]]; then
|
|
||||||
vendor/bin/monorepo-builder split -v
|
|
||||||
composer rector-prefixed
|
|
||||||
fi
|
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.composer/cache
|
- $HOME/.composer/cache
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
parameters:
|
|
||||||
directories_to_repositories:
|
|
||||||
packages/NodeTypeResolver: 'git@github.com:rectorphp/node-type-resolver.git'
|
|
|
@ -1,26 +0,0 @@
|
||||||
language: php
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- php: 7.1
|
|
||||||
env: PHPUNIT_FLAGS="--coverage-clover coverage.xml"
|
|
||||||
- php: 7.1
|
|
||||||
env: COMPOSER_FLAGS="--prefer-lowest"
|
|
||||||
- php: 7.2
|
|
||||||
|
|
||||||
install:
|
|
||||||
- composer update $COMPOSER_FLAGS
|
|
||||||
|
|
||||||
script:
|
|
||||||
- vendor/bin/phpunit $PHPUNIT_FLAGS
|
|
||||||
|
|
||||||
after_script:
|
|
||||||
# upload coverage.xml to Coveralls
|
|
||||||
- |
|
|
||||||
if [[ $PHPUNIT_FLAGS != "" ]]; then
|
|
||||||
wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.1.0/php-coveralls.phar;
|
|
||||||
php php-coveralls.phar --verbose;
|
|
||||||
fi
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email: false
|
|
|
@ -1,198 +0,0 @@
|
||||||
# Node Type Resolver
|
|
||||||
|
|
||||||
This package detects **class, interface and trait types** for classes, variables and properties. Those types are resolved by `NodeTypeResolver` service. It uses PHPStan for `PhpParser\Node\Expr` nodes and own type resolvers for other nodes like `PhpParser\Node\Stmt\Class_`, `PhpParser\Node\Stmt\Interface_` or `PhpParser\Node\Stmt\Trait_`.
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
composer require rector/node-type-resolver
|
|
||||||
```
|
|
||||||
|
|
||||||
You first need to integrate `Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator` to you application. It will traverse nodes and decorate with attributes that you can use right away and also attributes that are required for `Rector\NodeTypeResolver\NodeTypeResolver`.
|
|
||||||
|
|
||||||
This package works best in Symfony Kernel application, but is also available in standalone use thanks to decoupled container factory.
|
|
||||||
|
|
||||||
### A. Symfony Application
|
|
||||||
|
|
||||||
Import `services.yml` in your Symfony config:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# your-app/config.yml
|
|
||||||
imports:
|
|
||||||
- { resource: 'vendor/rector/node-type-resolver/config/config.yml' }
|
|
||||||
```
|
|
||||||
|
|
||||||
Require `Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator` in the constructor:
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace YourApp;
|
|
||||||
|
|
||||||
use PhpParser\Parser;
|
|
||||||
use Rector\NodeTypeResolver\Node\MetadataAttribute;
|
|
||||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
|
||||||
|
|
||||||
final class SomeClass
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var Parser
|
|
||||||
*/
|
|
||||||
private $parser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator
|
|
||||||
*/
|
|
||||||
private $nodeScopeAndMetadataDecorator;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
Parser $parser,
|
|
||||||
NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator
|
|
||||||
) {
|
|
||||||
$this->parser = $parser;
|
|
||||||
$this->nodeScopeAndMetadataDecorator = $nodeScopeAndMetadataDecorator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function run(): void
|
|
||||||
{
|
|
||||||
$someFilePath = __DIR__ . '/SomeFile.php';
|
|
||||||
$nodes = $this->parser->parse(file_get_contents($someFilePath));
|
|
||||||
|
|
||||||
$decoratedNodes = $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($nodes, $someFilePath);
|
|
||||||
|
|
||||||
foreach ($decoratedNodes as $node) {
|
|
||||||
$className = $node->getAttribute(MetadataAttribute::CLASS_NAME);
|
|
||||||
// "string" with class name
|
|
||||||
var_dump($className);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do whatever you need :)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### B. Standalone PHP Code
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
use Rector\NodeTypeResolver\DependencyInjection\NodeTypeResolverContainerFactory;
|
|
||||||
use Rector\NodeTypeResolver\Node\MetadataAttribute;
|
|
||||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
|
||||||
use PhpParser\ParserFactory;
|
|
||||||
|
|
||||||
$phpParser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
|
|
||||||
|
|
||||||
$someFilePath = __DIR__ . '/SomeFile.php';
|
|
||||||
$nodes = $phpParser->parse(file_get_contents($someFilePath));
|
|
||||||
|
|
||||||
$nodeTypeResolverContainer = (new NodeTypeResolverContainerFactory())->create();
|
|
||||||
/** @var NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator */
|
|
||||||
$nodeScopeAndMetadataDecorator = $nodeTypeResolverContainer->get(NodeScopeAndMetadataDecorator::class);
|
|
||||||
$decoratedNodes = $nodeScopeAndMetadataDecorator->decorateNodesFromFile($nodes, $someFilePath);
|
|
||||||
|
|
||||||
foreach ($decoratedNodes as $node) {
|
|
||||||
$className = $node->getAttribute(MetadataAttribute::CLASS_NAME);
|
|
||||||
// "string" with class name
|
|
||||||
var_dump($className);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
After this integration you have new attributes you can work with.
|
|
||||||
|
|
||||||
### Attributes
|
|
||||||
|
|
||||||
These attributes are always available anywhere inside the Node tree. That means that `CLASS_NAME` is available **in every node that is in the class**. That way you can easily get class name on `Property` node.
|
|
||||||
|
|
||||||
#### Namespaces
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
//@todo examples of dump
|
|
||||||
|
|
||||||
use Rector\NodeTypeResolver\Node\MetadataAttribute;
|
|
||||||
|
|
||||||
// string name of current namespace
|
|
||||||
$namespaceName = $node->setAttribute(MetadataAttribute::NAMESPACE_NAME, $this->namespaceName);
|
|
||||||
|
|
||||||
// instance of "PhpParser\Node\Stmt\Namespace_"
|
|
||||||
$namespaceNode = $node->setAttribute(MetadataAttribute::NAMESPACE_NODE, $this->namespaceNode);
|
|
||||||
|
|
||||||
// instances of "PhpParser\Node\Stmt\Use_"
|
|
||||||
$useNodes = $node->setAttribute(MetadataAttribute::USE_NODES, $this->useNodes);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Classes
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
//@todo examples of dump
|
|
||||||
|
|
||||||
use Rector\NodeTypeResolver\Node\MetadataAttribute;
|
|
||||||
|
|
||||||
// string name of current class
|
|
||||||
$className = $node->getAttribute(MetadataAttribute::CLASS_NAME);
|
|
||||||
|
|
||||||
// instance of "PhpParser\Node\Stmt\Class_"
|
|
||||||
$classNode = $node->getAttribute(MetadataAttribute::CLASS_NODE);
|
|
||||||
|
|
||||||
// string name of current class
|
|
||||||
$parentClassName = $node->getAttribute(MetadataAttribute::PARENT_CLASS_NAME);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Methods
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
use Rector\NodeTypeResolver\Node\MetadataAttribute;
|
|
||||||
|
|
||||||
//@todo examples of dump
|
|
||||||
|
|
||||||
// string name of current method
|
|
||||||
$methodName = $node->getAttribute(MetadataAttribute::METHOD_NAME);
|
|
||||||
|
|
||||||
// instance of "PhpParser\Node\Stmt\ClassMethod"
|
|
||||||
$methodNode = $node->getAttribute(MetadataAttribute::METHOD_NODE);
|
|
||||||
|
|
||||||
// string name of current method call ($this->get => "get")
|
|
||||||
$methodCallName = $node->getAttribute(MetadataAttribute::METHOD_NAME);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get Types of Node
|
|
||||||
|
|
||||||
`Rector\NodeTypeResolver\NodeTypeResolver` helps you detect object types for any node that can have one.
|
|
||||||
|
|
||||||
Get it via constructor or `$container->get(Rector\NodeTypeResolver\NodeTypeResolver::class)`;
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
use PhpParser\Node\Stmt\Class_;
|
|
||||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
|
||||||
|
|
||||||
// previously processed nodes
|
|
||||||
$nodes = [...];
|
|
||||||
/** @var NodeTypeResolver $nodeTypeResolver */
|
|
||||||
$nodeTypeResolver = ...;
|
|
||||||
|
|
||||||
foreach ($nodes as $node) {
|
|
||||||
if ($node instanceof Class_) {
|
|
||||||
$classNodeTypes = $nodeTypeResolver->resolve($node);
|
|
||||||
var_dump($classNodeTypes); // array of strings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Inspiration
|
|
||||||
|
|
||||||
Huge thanks for inspiration of this integration belongs to [PHPStanScopeVisitor](https://github.com/silverstripe/silverstripe-upgrader/blob/532182b23e854d02e0b27e68ebc394f436de0682/src/UpgradeRule/PHP/Visitor/PHPStanScopeVisitor.php) by [SilverStripe](https://github.com/silverstripe/) - Thank you ❤️️ !
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
{
|
|
||||||
"name": "rector/node-type-resolver",
|
|
||||||
"description": "This package detects class, interface and trait types for classes, variables and properties.",
|
|
||||||
"license": "MIT",
|
|
||||||
"authors": [
|
|
||||||
{ "name": "Tomas Votruba", "email": "tomas.vot@gmail.com", "homepage": "https://tomasvotruba.com" }
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": "^7.1",
|
|
||||||
"nikic/php-parser": "^4.0.3",
|
|
||||||
"phpstan/phpstan": "^0.10.3",
|
|
||||||
"symfony/dependency-injection": "^3.4|^4.1",
|
|
||||||
"symfony/finder": "^3.4|^4.1",
|
|
||||||
"symplify/better-phpdoc-parser": "^5.0",
|
|
||||||
"rector/utils": "dev-master",
|
|
||||||
"symplify/package-builder": "^5.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^7.3"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Rector\\NodeTypeResolver\\": "src"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-4": {
|
|
||||||
"Rector\\NodeTypeResolver\\Tests\\": "tests"
|
|
||||||
},
|
|
||||||
"classmap": [
|
|
||||||
"tests"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"sort-packages": true
|
|
||||||
},
|
|
||||||
"minimum-stability": "dev",
|
|
||||||
"prefer-stable": true
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Rector\NodeTypeResolver\DependencyInjection;
|
|
||||||
|
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
|
|
||||||
final class NodeTypeResolverContainerFactory
|
|
||||||
{
|
|
||||||
public function create(): ContainerInterface
|
|
||||||
{
|
|
||||||
$kernel = new NodeTypeResolverKernel();
|
|
||||||
$kernel->boot();
|
|
||||||
|
|
||||||
return $kernel->getContainer();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createWithConfig(string $config): ContainerInterface
|
|
||||||
{
|
|
||||||
$kernel = new NodeTypeResolverKernel($config);
|
|
||||||
$kernel->boot();
|
|
||||||
|
|
||||||
return $kernel->getContainer();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Rector\NodeTypeResolver\DependencyInjection;
|
|
||||||
|
|
||||||
use Symfony\Component\Config\Loader\LoaderInterface;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
||||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
|
||||||
use Symfony\Component\HttpKernel\Kernel;
|
|
||||||
use Symplify\PackageBuilder\DependencyInjection\CompilerPass\AutoBindParametersCompilerPass;
|
|
||||||
|
|
||||||
final class NodeTypeResolverKernel extends Kernel
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var string|null
|
|
||||||
*/
|
|
||||||
private $config;
|
|
||||||
|
|
||||||
public function __construct(?string $config = null)
|
|
||||||
{
|
|
||||||
$this->config = $config;
|
|
||||||
|
|
||||||
parent::__construct('dev', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function registerContainerConfiguration(LoaderInterface $loader): void
|
|
||||||
{
|
|
||||||
$loader->load(__DIR__ . '/../../src/config/config.yml');
|
|
||||||
|
|
||||||
if ($this->config) {
|
|
||||||
$loader->load($this->config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return BundleInterface[]
|
|
||||||
*/
|
|
||||||
public function registerBundles(): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCacheDir(): string
|
|
||||||
{
|
|
||||||
return sys_get_temp_dir() . '/_rector_node_type_resolver_cache';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLogDir(): string
|
|
||||||
{
|
|
||||||
return sys_get_temp_dir() . '/_rector_type_resolver_test_log';
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function build(ContainerBuilder $containerBuilder): void
|
|
||||||
{
|
|
||||||
$containerBuilder->addCompilerPass(new AutoBindParametersCompilerPass());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Rector\NodeTypeResolver;
|
|
||||||
|
|
||||||
use PHPStan\Broker\Broker;
|
|
||||||
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
|
|
||||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeToStringResolver;
|
|
||||||
use Rector\NodeTypeResolver\Reflection\ClassReflectionTypesResolver;
|
|
||||||
use Symfony\Component\DependencyInjection\Container;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
||||||
|
|
||||||
final class NodeTypeResolverFactory
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var ContainerInterface|Container
|
|
||||||
*/
|
|
||||||
private $container;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ContainerInterface|Container $container
|
|
||||||
*/
|
|
||||||
public function __construct(ContainerInterface $container)
|
|
||||||
{
|
|
||||||
$this->container = $container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create(): NodeTypeResolver
|
|
||||||
{
|
|
||||||
/** @var TypeToStringResolver $typeToStringResolver */
|
|
||||||
$typeToStringResolver = $this->container->get(TypeToStringResolver::class);
|
|
||||||
|
|
||||||
/** @var Broker $broker */
|
|
||||||
$broker = $this->container->get(Broker::class);
|
|
||||||
|
|
||||||
/** @var ClassReflectionTypesResolver $classReflectionTypesResolver */
|
|
||||||
$classReflectionTypesResolver = $this->container->get(ClassReflectionTypesResolver::class);
|
|
||||||
|
|
||||||
$nodeTypeResolver = new NodeTypeResolver($typeToStringResolver, $broker, $classReflectionTypesResolver);
|
|
||||||
|
|
||||||
foreach ($this->container->getServiceIds() as $serviceId) {
|
|
||||||
if (! is_a($serviceId, PerNodeTypeResolverInterface::class, true)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var PerNodeTypeResolverInterface $perNodeTypeResolver */
|
|
||||||
$perNodeTypeResolver = $this->container->get($serviceId);
|
|
||||||
$nodeTypeResolver->addPerNodeTypeResolver($perNodeTypeResolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $nodeTypeResolver;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,12 @@
|
||||||
imports:
|
imports:
|
||||||
# to cover prefixed rector and projects autoload - monorepo
|
|
||||||
- { resource: '../../../../vendor/symplify/better-phpdoc-parser/src/config/config.yml' , ignore_errors: true }
|
|
||||||
# to cover installed as dependency
|
|
||||||
- { resource: '../../../../../../symplify/better-phpdoc-parser/src/config/config.yml' , ignore_errors: true }
|
|
||||||
|
|
||||||
# rector/utils package
|
|
||||||
- { resource: '../../../Utils/src/config/services.yml' }
|
|
||||||
|
|
||||||
- { resource: 'services.yml' }
|
- { resource: 'services.yml' }
|
||||||
|
- { resource: '%vendor%/symplify/better-phpdoc-parser/src/config/config.yml' }
|
||||||
|
|
||||||
|
parameters:
|
||||||
|
collectors:
|
||||||
|
-
|
||||||
|
main_type: 'Rector\NodeTypeResolver\NodeTypeResolver'
|
||||||
|
collected_type: 'Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface'
|
||||||
|
add_method: 'addPerNodeTypeResolver'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
services:
|
services:
|
||||||
_defaults:
|
_defaults:
|
||||||
# for "Rector\NodeTypeResolver\NodeTypeResolverFactory" standalone usage
|
|
||||||
public: true
|
public: true
|
||||||
autowire: true
|
autowire: true
|
||||||
|
|
||||||
Symplify\PackageBuilder\Parameter\ParameterProvider: ~
|
|
||||||
PhpParser\NodeVisitor\CloningVisitor: ~
|
|
||||||
PhpParser\NodeFinder: ~
|
|
||||||
|
|
||||||
# PHPStan
|
# PHPStan
|
||||||
PHPStan\Broker\Broker:
|
PHPStan\Broker\Broker:
|
||||||
factory: ['@Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory', 'createBroker']
|
factory: ['@Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory', 'createBroker']
|
||||||
|
|
|
@ -6,13 +6,12 @@ parameters:
|
||||||
|
|
||||||
services:
|
services:
|
||||||
_defaults:
|
_defaults:
|
||||||
# for "Rector\NodeTypeResolver\NodeTypeResolverFactory" standalone usage
|
|
||||||
public: true
|
public: true
|
||||||
autowire: true
|
autowire: true
|
||||||
|
|
||||||
Rector\NodeTypeResolver\:
|
Rector\NodeTypeResolver\:
|
||||||
resource: '../'
|
resource: '../'
|
||||||
exclude: '../{Contract,DependencyInjection/NodeTypeResolverKernel.php,DependencyInjection/NodeTypeResolverContainerFactory.php}'
|
exclude: '../{Contract}'
|
||||||
|
|
||||||
Rector\PhpParser\CurrentNodeProvider: ~
|
Rector\PhpParser\CurrentNodeProvider: ~
|
||||||
|
|
||||||
|
@ -21,7 +20,3 @@ services:
|
||||||
Rector\Printer\BetterStandardPrinter: ~
|
Rector\Printer\BetterStandardPrinter: ~
|
||||||
Rector\FileSystem\FilesFinder: ~
|
Rector\FileSystem\FilesFinder: ~
|
||||||
Rector\Utils\BetterNodeFinder: ~
|
Rector\Utils\BetterNodeFinder: ~
|
||||||
|
|
||||||
# factory to remove dependency on CompilerPass and make install DX smoother
|
|
||||||
Rector\NodeTypeResolver\NodeTypeResolver:
|
|
||||||
factory: ['@Rector\NodeTypeResolver\NodeTypeResolverFactory', 'create']
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Rector\NodeTypeResolver\Tests;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
use Rector\NodeTypeResolver\DependencyInjection\NodeTypeResolverContainerFactory;
|
|
||||||
|
|
||||||
abstract class AbstractNodeTypeResolverContainerAwareTestCase extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var ContainerInterface
|
|
||||||
*/
|
|
||||||
protected $container;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ContainerInterface
|
|
||||||
*/
|
|
||||||
private static $cachedContainer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a test case with the given name.
|
|
||||||
*
|
|
||||||
* @param mixed[] $data
|
|
||||||
*/
|
|
||||||
public function __construct(?string $name = null, array $data = [], string $dataName = '')
|
|
||||||
{
|
|
||||||
if (self::$cachedContainer === null) {
|
|
||||||
self::$cachedContainer = (new NodeTypeResolverContainerFactory())->createWithConfig(
|
|
||||||
__DIR__ . '/config/config.tests.yml'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->container = self::$cachedContainer;
|
|
||||||
|
|
||||||
parent::__construct($name, $data, $dataName);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,29 +3,35 @@
|
||||||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver;
|
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver;
|
||||||
|
|
||||||
use PhpParser\Node;
|
use PhpParser\Node;
|
||||||
|
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
||||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||||
use Rector\NodeTypeResolver\Tests\AbstractNodeTypeResolverContainerAwareTestCase;
|
use Rector\Parser\Parser;
|
||||||
use Rector\NodeTypeResolver\Tests\StandaloneNodeTraverserQueue;
|
use Rector\Tests\AbstractContainerAwareTestCase;
|
||||||
use Rector\Utils\BetterNodeFinder;
|
use Rector\Utils\BetterNodeFinder;
|
||||||
use Symfony\Component\Finder\SplFileInfo;
|
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||||
|
|
||||||
abstract class AbstractNodeTypeResolverTest extends AbstractNodeTypeResolverContainerAwareTestCase
|
abstract class AbstractNodeTypeResolverTest extends AbstractContainerAwareTestCase
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var BetterNodeFinder
|
|
||||||
*/
|
|
||||||
protected $betterNodeFinder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var NodeTypeResolver
|
* @var NodeTypeResolver
|
||||||
*/
|
*/
|
||||||
protected $nodeTypeResolver;
|
protected $nodeTypeResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var StandaloneNodeTraverserQueue
|
* @var BetterNodeFinder
|
||||||
*/
|
*/
|
||||||
private $standaloneNodeTraverserQueue;
|
private $betterNodeFinder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Parser
|
||||||
|
*/
|
||||||
|
private $parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var NodeScopeAndMetadataDecorator
|
||||||
|
*/
|
||||||
|
private $nodeScopeAndMetadataDecorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var ParameterProvider
|
* @var ParameterProvider
|
||||||
|
@ -35,9 +41,10 @@ abstract class AbstractNodeTypeResolverTest extends AbstractNodeTypeResolverCont
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
$this->betterNodeFinder = $this->container->get(BetterNodeFinder::class);
|
$this->betterNodeFinder = $this->container->get(BetterNodeFinder::class);
|
||||||
$this->standaloneNodeTraverserQueue = $this->container->get(StandaloneNodeTraverserQueue::class);
|
|
||||||
$this->parameterProvider = $this->container->get(ParameterProvider::class);
|
$this->parameterProvider = $this->container->get(ParameterProvider::class);
|
||||||
$this->nodeTypeResolver = $this->container->get(NodeTypeResolver::class);
|
$this->nodeTypeResolver = $this->container->get(NodeTypeResolver::class);
|
||||||
|
$this->parser = $this->container->get(Parser::class);
|
||||||
|
$this->nodeScopeAndMetadataDecorator = $this->container->get(NodeScopeAndMetadataDecorator::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,12 +60,14 @@ abstract class AbstractNodeTypeResolverTest extends AbstractNodeTypeResolverCont
|
||||||
/**
|
/**
|
||||||
* @return Node[]
|
* @return Node[]
|
||||||
*/
|
*/
|
||||||
protected function getNodesForFile(string $file): array
|
private function getNodesForFile(string $file): array
|
||||||
{
|
{
|
||||||
$fileInfo = new SplFileInfo($file, '', '');
|
$smartFileInfo = new SmartFileInfo($file);
|
||||||
|
|
||||||
$this->parameterProvider->changeParameter('source', [$file]);
|
$this->parameterProvider->changeParameter('source', [$file]);
|
||||||
|
|
||||||
return $this->standaloneNodeTraverserQueue->processFileInfo($fileInfo);
|
$nodes = $this->parser->parseFile($smartFileInfo->getRealPath());
|
||||||
|
|
||||||
|
return $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($nodes, $smartFileInfo->getRealPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ namespace Rector\NodeTypeResolver\Tests\PhpDoc\NodeAnalyzer;
|
||||||
use PhpParser\Comment\Doc;
|
use PhpParser\Comment\Doc;
|
||||||
use PhpParser\Node\Scalar\String_;
|
use PhpParser\Node\Scalar\String_;
|
||||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockAnalyzer;
|
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockAnalyzer;
|
||||||
use Rector\NodeTypeResolver\Tests\AbstractNodeTypeResolverContainerAwareTestCase;
|
use Rector\Tests\AbstractContainerAwareTestCase;
|
||||||
use function Safe\sprintf;
|
use function Safe\sprintf;
|
||||||
|
|
||||||
final class DocBlockAnalyzerTest extends AbstractNodeTypeResolverContainerAwareTestCase
|
final class DocBlockAnalyzerTest extends AbstractContainerAwareTestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var DocBlockAnalyzer
|
* @var DocBlockAnalyzer
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Rector\NodeTypeResolver\Tests;
|
|
||||||
|
|
||||||
use PhpParser\Node;
|
|
||||||
use PhpParser\Parser;
|
|
||||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
|
||||||
use Symfony\Component\Finder\SplFileInfo;
|
|
||||||
|
|
||||||
final class StandaloneNodeTraverserQueue
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var Parser
|
|
||||||
*/
|
|
||||||
private $parser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var NodeScopeAndMetadataDecorator
|
|
||||||
*/
|
|
||||||
private $nodeScopeAndMetadataDecorator;
|
|
||||||
|
|
||||||
public function __construct(Parser $parser, NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator)
|
|
||||||
{
|
|
||||||
$this->parser = $parser;
|
|
||||||
$this->nodeScopeAndMetadataDecorator = $nodeScopeAndMetadataDecorator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Node[]
|
|
||||||
*/
|
|
||||||
public function processFileInfo(SplFileInfo $fileInfo): array
|
|
||||||
{
|
|
||||||
$nodes = $this->parser->parse($fileInfo->getContents());
|
|
||||||
|
|
||||||
return $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($nodes, $fileInfo->getRealPath());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
services:
|
|
||||||
_defaults:
|
|
||||||
autowire: true
|
|
||||||
public: true
|
|
||||||
|
|
||||||
PhpParser\ParserFactory: ~
|
|
||||||
PhpParser\Parser:
|
|
||||||
factory: ['@PhpParser\ParserFactory', 'create']
|
|
||||||
arguments:
|
|
||||||
$kind: !php/const PhpParser\ParserFactory::PREFER_PHP7
|
|
||||||
|
|
||||||
Rector\NodeTypeResolver\Tests\StandaloneNodeTraverserQueue: ~
|
|
|
@ -35,9 +35,6 @@ parameters:
|
||||||
# already fixed, invalidated cache?
|
# already fixed, invalidated cache?
|
||||||
- '#Access to an undefined property PhpParser\\Node\\Expr::\$args#'
|
- '#Access to an undefined property PhpParser\\Node\\Expr::\$args#'
|
||||||
|
|
||||||
# symfony container autowire interface falsy
|
|
||||||
- '#Call to an undefined method Symfony\\Component\\DependencyInjection\\ContainerInterface::getServiceIds\(\)#'
|
|
||||||
|
|
||||||
# nette container
|
# nette container
|
||||||
- '#Method Rector\\NodeTypeResolver\\DependencyInjection\\PHPStanServicesFactory::create(.*?)() should return (.*?) but returns object#'
|
- '#Method Rector\\NodeTypeResolver\\DependencyInjection\\PHPStanServicesFactory::create(.*?)() should return (.*?) but returns object#'
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use Nette\Utils\Strings;
|
||||||
use Rector\Utils\FilesystemTweaker;
|
use Rector\Utils\FilesystemTweaker;
|
||||||
use Symfony\Component\Finder\Finder;
|
use Symfony\Component\Finder\Finder;
|
||||||
use Symfony\Component\Finder\SplFileInfo;
|
use Symfony\Component\Finder\SplFileInfo;
|
||||||
|
use Symplify\PackageBuilder\FileSystem\SmartFileInfo;
|
||||||
|
|
||||||
final class FilesFinder
|
final class FilesFinder
|
||||||
{
|
{
|
||||||
|
@ -49,7 +50,7 @@ final class FilesFinder
|
||||||
|
|
||||||
$splFileInfos = [];
|
$splFileInfos = [];
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
$splFileInfos[] = new SplFileInfo($file, '', '');
|
$splFileInfos[] = new SmartFileInfo($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
$splFileInfos = array_merge($splFileInfos, $this->findInDirectories($directories, $suffixes));
|
$splFileInfos = array_merge($splFileInfos, $this->findInDirectories($directories, $suffixes));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user