-
-
Notifications
You must be signed in to change notification settings - Fork 708
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f586d42
commit 2ad18be
Showing
17 changed files
with
724 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,7 @@ services: | |
parameters: | ||
sets: | ||
- 'psr12' | ||
- 'php70' | ||
- 'php71' | ||
- 'symplify' | ||
- 'common' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
services: | ||
_defaults: | ||
autowire: true | ||
public: true | ||
|
||
Rector\AttributeAwarePhpDoc\: | ||
resource: '../src' | ||
exclude: | ||
- '../src/Ast/*' |
44 changes: 44 additions & 0 deletions
44
packages/AttributeAwarePhpDoc/src/AttributeAwareNodeFactoryCollector.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\AttributeAwarePhpDoc; | ||
|
||
use Rector\AttributeAwarePhpDoc\Contract\AttributeNodeAwareFactory\AttributeNodeAwareFactoryInterface; | ||
|
||
final class AttributeAwareNodeFactoryCollector | ||
{ | ||
/** | ||
* @var AttributeNodeAwareFactoryInterface[] | ||
*/ | ||
private $attributeAwareNodeFactories = []; | ||
|
||
/** | ||
* @param AttributeNodeAwareFactoryInterface[] $attributeAwareNodeFactories | ||
*/ | ||
public function __construct(array $attributeAwareNodeFactories) | ||
{ | ||
$this->attributeAwareNodeFactories = $attributeAwareNodeFactories; | ||
} | ||
|
||
/** | ||
* @return AttributeNodeAwareFactoryInterface[] | ||
*/ | ||
public function provide(): array | ||
{ | ||
return $this->attributeAwareNodeFactories; | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
public function getSupportedNodeClasses(): array | ||
{ | ||
$supportedNodeClasses = []; | ||
foreach ($this->attributeAwareNodeFactories as $attributeAwareNodeFactory) { | ||
$supportedNodeClasses[] = $attributeAwareNodeFactory->getOriginalNodeClass(); | ||
} | ||
|
||
return $supportedNodeClasses; | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
...AwarePhpDoc/src/Contract/AttributeNodeAwareFactory/AttributeNodeAwareFactoryInterface.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\AttributeAwarePhpDoc\Contract\AttributeNodeAwareFactory; | ||
|
||
use PHPStan\PhpDocParser\Ast\Node; | ||
use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface; | ||
|
||
interface AttributeNodeAwareFactoryInterface | ||
{ | ||
public function getOriginalNodeClass(): string; | ||
|
||
public function isMatch(Node $node): bool; | ||
|
||
public function create(Node $node): AttributeAwareNodeInterface; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
services: | ||
_defaults: | ||
public: true | ||
autowire: true | ||
autoconfigure: true | ||
|
||
Rector\Utils\PHPStanAttributeTypeSyncer\: | ||
resource: '../src' | ||
exclude: | ||
- '../src/ValueObject/*' |
45 changes: 45 additions & 0 deletions
45
utils/PHPStanAttributeTypeSyncer/src/ClassNaming/AttributeClassNaming.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Utils\PHPStanAttributeTypeSyncer\ClassNaming; | ||
|
||
use Rector\CodingStyle\Naming\ClassNaming; | ||
use Rector\Utils\PHPStanAttributeTypeSyncer\ValueObject\Paths; | ||
|
||
final class AttributeClassNaming | ||
{ | ||
/** | ||
* @var ClassNaming | ||
*/ | ||
private $classNaming; | ||
|
||
public function __construct(ClassNaming $classNaming) | ||
{ | ||
$this->classNaming = $classNaming; | ||
} | ||
|
||
public function createAttributeAwareShortClassName(string $nodeClass): string | ||
{ | ||
$shortMissingNodeClass = $this->classNaming->getShortName($nodeClass); | ||
|
||
return 'AttributeAware' . $shortMissingNodeClass; | ||
} | ||
|
||
public function createAttributeAwareFactoryShortClassName(string $nodeClass): string | ||
{ | ||
$shortMissingNodeClass = $this->classNaming->getShortName($nodeClass); | ||
|
||
return 'AttributeAware' . $shortMissingNodeClass . 'Factory'; | ||
} | ||
|
||
public function createAttributeAwareClassName(string $nodeClass): string | ||
{ | ||
return Paths::NAMESPACE_PHPDOC_NODE . '\\' . $this->createAttributeAwareShortClassName($nodeClass); | ||
} | ||
|
||
public function createAttributeAwareFactoryClassName(string $nodeClass): string | ||
{ | ||
return Paths::NAMESPACE_NODE_FACTORY . '\\' . $this->createAttributeAwareFactoryShortClassName($nodeClass); | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
utils/PHPStanAttributeTypeSyncer/src/Command/SyncTypesCommand.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Utils\PHPStanAttributeTypeSyncer\Command; | ||
|
||
use Rector\AttributeAwarePhpDoc\AttributeAwareNodeFactoryCollector; | ||
use Rector\Console\Command\AbstractCommand; | ||
use Rector\Console\Shell; | ||
use Rector\Utils\PHPStanAttributeTypeSyncer\Finder\NodeClassFinder; | ||
use Rector\Utils\PHPStanAttributeTypeSyncer\Generator\AttributeAwareNodeFactoryGenerator; | ||
use Rector\Utils\PHPStanAttributeTypeSyncer\Generator\AttributeAwareNodeGenerator; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Console\Style\SymfonyStyle; | ||
use Symplify\PackageBuilder\Console\Command\CommandNaming; | ||
|
||
final class SyncTypesCommand extends AbstractCommand | ||
{ | ||
/** | ||
* @var AttributeAwareNodeFactoryCollector | ||
*/ | ||
private $attributeAwareNodeFactoryCollector; | ||
|
||
/** | ||
* @var SymfonyStyle | ||
*/ | ||
private $symfonyStyle; | ||
|
||
/** | ||
* @var NodeClassFinder | ||
*/ | ||
private $nodeClassFinder; | ||
|
||
/** | ||
* @var AttributeAwareNodeGenerator | ||
*/ | ||
private $attributeAwareNodeGenerator; | ||
|
||
/** | ||
* @var AttributeAwareNodeFactoryGenerator | ||
*/ | ||
private $attributeAwareNodeFactoryGenerator; | ||
|
||
public function __construct( | ||
AttributeAwareNodeFactoryCollector $attributeAwareNodeFactoryCollector, | ||
SymfonyStyle $symfonyStyle, | ||
NodeClassFinder $nodeClassFinder, | ||
AttributeAwareNodeGenerator $attributeAwareNodeGenerator, | ||
AttributeAwareNodeFactoryGenerator $attributeAwareNodeFactoryGenerator | ||
) { | ||
$this->attributeAwareNodeFactoryCollector = $attributeAwareNodeFactoryCollector; | ||
$this->symfonyStyle = $symfonyStyle; | ||
$this->nodeClassFinder = $nodeClassFinder; | ||
$this->attributeAwareNodeGenerator = $attributeAwareNodeGenerator; | ||
$this->attributeAwareNodeFactoryGenerator = $attributeAwareNodeFactoryGenerator; | ||
|
||
parent::__construct(); | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this->setName(CommandNaming::classToName(self::class)); | ||
$this->setDescription('[Dev] Synchronize PHPStan types to attribute aware types in Rectors'); | ||
} | ||
|
||
protected function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$missingNodeClasses = $this->getMissingNodeClasses(); | ||
if ($missingNodeClasses === []) { | ||
$this->symfonyStyle->success( | ||
'All PHPStan Doc Parser nodes are covered with attribute aware mirror in Rector' | ||
); | ||
|
||
return Shell::CODE_SUCCESS; | ||
} | ||
|
||
$this->symfonyStyle->error('These classes are missing their attribute aware brother'); | ||
|
||
foreach ($missingNodeClasses as $missingNodeClass) { | ||
// 1. generate node | ||
$this->attributeAwareNodeGenerator->generateFromPhpDocParserNodeClass($missingNodeClass); | ||
|
||
// 2. generate node factory... | ||
$this->attributeAwareNodeFactoryGenerator->generateFromPhpDocParserNodeClass($missingNodeClass); | ||
} | ||
|
||
return Shell::CODE_ERROR; | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
private function getMissingNodeClasses(): array | ||
{ | ||
$phpDocParserTagValueNodeClasses = $this->nodeClassFinder->findCurrentPHPDocParserNodeClasses(); | ||
$supportedNodeClasses = $this->attributeAwareNodeFactoryCollector->getSupportedNodeClasses(); | ||
|
||
return array_diff($phpDocParserTagValueNodeClasses, $supportedNodeClasses); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
utils/PHPStanAttributeTypeSyncer/src/Finder/NodeClassFinder.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Utils\PHPStanAttributeTypeSyncer\Finder; | ||
|
||
use Nette\Loaders\RobotLoader; | ||
|
||
final class NodeClassFinder | ||
{ | ||
/** | ||
* @return string[] | ||
*/ | ||
public function findCurrentPHPDocParserNodeClasses(): array | ||
{ | ||
return $this->findClassesByNamePatternInDirectories( | ||
'*Node.php', | ||
[ | ||
// @todo not sure if needed | ||
// __DIR__ . '/../../../../vendor/phpstan/phpdoc-parser/src/Ast/Type', | ||
__DIR__ . '/../../../../vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc', | ||
] | ||
); | ||
} | ||
|
||
/** | ||
* @param string[] $directories | ||
* @return string[] | ||
*/ | ||
private function findClassesByNamePatternInDirectories(string $namePattern, array $directories): array | ||
{ | ||
$robotLoader = new RobotLoader(); | ||
foreach ($directories as $directory) { | ||
$robotLoader->addDirectory($directory); | ||
} | ||
|
||
$robotLoader->setTempDirectory(sys_get_temp_dir() . '/_phpdoc_parser_ast'); | ||
$robotLoader->acceptFiles = [$namePattern]; | ||
$robotLoader->rebuild(); | ||
|
||
$classLikesToPaths = $robotLoader->getIndexedClasses(); | ||
|
||
$classLikes = array_keys($classLikesToPaths); | ||
$excludedClasses = ['PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode']; | ||
|
||
// keep only classes, skip interfaces | ||
$classes = []; | ||
foreach ($classLikes as $classLike) { | ||
if (! class_exists($classLike)) { | ||
continue; | ||
} | ||
|
||
$classes[] = $classLike; | ||
} | ||
|
||
return array_diff($classes, $excludedClasses); | ||
} | ||
} |
Oops, something went wrong.