[Docs] update docs and type check (#4241)

This commit is contained in:
Tomas Votruba 2020-09-18 11:50:55 +02:00 committed by GitHub
parent 1c2afb2e56
commit 2243583537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 412 additions and 149 deletions

View File

@ -203,6 +203,8 @@
"Rector\\Php73\\Tests\\": "rules/php73/tests",
"Rector\\Php74\\Tests\\": "rules/php74/tests",
"Rector\\Php80\\Tests\\": "rules/php80/tests",
"Rector\\Utils\\NodeDocumentationGenerator\\": "utils/node-documentation-generator/src",
"Rector\\Utils\\NodeDocumentationGenerator\\Tests\\": "utils/node-documentation-generator/tests",
"Rector\\PHPOffice\\Tests\\": "rules/php-office/tests",
"Rector\\PhpDeglobalize\\Tests\\": "rules/php-deglobalize/tests",
"Rector\\PhpSpecToPHPUnit\\Tests\\": "rules/php-spec-to-phpunit/tests",
@ -220,7 +222,7 @@
"Rector\\Transform\\Tests\\": "rules/transform/tests",
"Rector\\Twig\\Tests\\": "rules/twig/tests",
"Rector\\TypeDeclaration\\Tests\\": "rules/type-declaration/tests",
"Rector\\Utils\\DocumentationGenerator\\": "utils/documentation-generator/src",
"Rector\\Utils\\DocumentationGenerator\\": "utils/node-documentation-generator/src",
"Rector\\Utils\\ProjectValidator\\": "utils/project-validator/src",
"Rector\\Utils\\DoctrineAnnotationParserSyncer\\": "utils/doctrine-annotation-parser-syncer/src",
"Rector\\Utils\\PHPStanAttributeTypeSyncer\\": "utils/phpstan-attribute-type-syncer/src",

View File

@ -19,7 +19,7 @@
#### Example PHP Code
```php
$someVariable[0]
$variableName[0]
```
#### Public Properties
@ -87,7 +87,7 @@ fn() => 1
#### Example PHP Code
```php
$someVariable = 'some value'
$variableName = 'some value'
```
#### Public Properties
@ -104,7 +104,7 @@ $someVariable = 'some value'
#### Example PHP Code
```php
$someVariable =& $someOtherVariable
$variableName =& $someOtherVariable
```
#### Public Properties
@ -121,7 +121,7 @@ $someVariable =& $someOtherVariable
#### Example PHP Code
```php
~$someVariable
~$variableName
```
#### Public Properties
@ -153,7 +153,7 @@ $someVariable =& $someOtherVariable
#### Example PHP Code
```php
SomeClass::SOME_CONSTANT
SomeClassName::SOME_CONSTANT
```
#### Public Properties
@ -170,7 +170,7 @@ SomeClass::SOME_CONSTANT
#### Example PHP Code
```php
clone $someVariable
clone $variableName
```
#### Public Properties
@ -206,7 +206,7 @@ function () {
#### Example PHP Code
```php
$someVariable
$variableName
```
#### Public Properties
@ -239,7 +239,7 @@ true
#### Example PHP Code
```php
empty($someVariable)
empty($variableName)
```
#### Public Properties
@ -255,7 +255,7 @@ empty($someVariable)
#### Example PHP Code
```php
@$someVariable
@$variableName
```
#### Public Properties
@ -318,7 +318,7 @@ functionCall()
#### Example PHP Code
```php
include $someVariable
include $variableName
```
#### Public Properties
@ -335,7 +335,7 @@ include $someVariable
#### Example PHP Code
```php
$someVariable instanceof SomeClass
$variableName instanceof SomeClassName
```
#### Public Properties
@ -352,7 +352,7 @@ $someVariable instanceof SomeClass
#### Example PHP Code
```php
isset($variable)
isset($variableName)
```
#### Public Properties
@ -368,7 +368,7 @@ isset($variable)
#### Example PHP Code
```php
list($someVariable)
list($variableName)
```
#### Public Properties
@ -384,7 +384,7 @@ list($someVariable)
#### Example PHP Code
```php
match ($variable) {
match ($variableName) {
1 => 'yes',
}
```
@ -440,7 +440,7 @@ new class
#### Example PHP Code
```php
$someVariable?->someMethod()
$variableName?->methodName()
```
#### Public Properties
@ -458,7 +458,7 @@ $someVariable?->someMethod()
#### Example PHP Code
```php
$someVariable?->somePropety
$variableName?->somePropety
```
#### Public Properties
@ -475,7 +475,7 @@ $someVariable?->somePropety
#### Example PHP Code
```php
$someVariable--
$variableName--
```
#### Public Properties
@ -491,7 +491,7 @@ $someVariable--
#### Example PHP Code
```php
$someVariable++
$variableName++
```
#### Public Properties
@ -507,7 +507,7 @@ $someVariable++
#### Example PHP Code
```php
--$someVariable
--$variableName
```
#### Public Properties
@ -523,7 +523,7 @@ $someVariable++
#### Example PHP Code
```php
++$someVariable
++$variableName
```
#### Public Properties
@ -539,7 +539,7 @@ $someVariable++
#### Example PHP Code
```php
print $someVariable
print $variableName
```
#### Public Properties
@ -555,7 +555,7 @@ print $someVariable
#### Example PHP Code
```php
$someVariable->propertyName
$variableName->propertyName
```
#### Public Properties
@ -588,7 +588,7 @@ $someVariable->propertyName
#### Example PHP Code
```php
SomeClass::methodName()
SomeClassName::methodName()
```
#### Public Properties
@ -606,7 +606,7 @@ SomeClass::methodName()
#### Example PHP Code
```php
SomeClass::$someProperty
SomeClassName::$someProperty
```
#### Public Properties
@ -623,7 +623,7 @@ SomeClass::$someProperty
#### Example PHP Code
```php
$someVariable ? true : false
$variableName ? true : false
```
#### Public Properties
@ -641,7 +641,7 @@ $someVariable ? true : false
#### Example PHP Code
```php
throw $someVariable;
throw $variableName;
```
#### Public Properties
@ -657,7 +657,7 @@ throw $someVariable;
#### Example PHP Code
```php
-$someVariable
-$variableName
```
#### Public Properties
@ -673,7 +673,7 @@ throw $someVariable;
#### Example PHP Code
```php
+$someVariable
+$variableName
```
#### Public Properties
@ -689,7 +689,7 @@ throw $someVariable;
#### Example PHP Code
```php
$someVariable
$variableName
```
#### Public Properties
@ -705,7 +705,7 @@ $someVariable
#### Example PHP Code
```php
yield from $someVariable
yield from $variableName
```
#### Public Properties
@ -738,7 +738,7 @@ yield
#### Example PHP Code
```php
$variable &= 'value'
$variableName &= 'value'
```
#### Public Properties
@ -755,7 +755,7 @@ $variable &= 'value'
#### Example PHP Code
```php
$variable |= 'value'
$variableName |= 'value'
```
#### Public Properties
@ -772,7 +772,7 @@ $variable |= 'value'
#### Example PHP Code
```php
$variable ^= 'value'
$variableName ^= 'value'
```
#### Public Properties
@ -789,7 +789,7 @@ $variable ^= 'value'
#### Example PHP Code
```php
$variable ??= 'value'
$variableName ??= 'value'
```
#### Public Properties
@ -806,7 +806,7 @@ $variable ??= 'value'
#### Example PHP Code
```php
$variable .= 'value'
$variableName .= 'value'
```
#### Public Properties
@ -823,7 +823,7 @@ $variable .= 'value'
#### Example PHP Code
```php
$variable /= 'value'
$variableName /= 'value'
```
#### Public Properties
@ -840,7 +840,7 @@ $variable /= 'value'
#### Example PHP Code
```php
$variable -= 'value'
$variableName -= 'value'
```
#### Public Properties
@ -857,7 +857,7 @@ $variable -= 'value'
#### Example PHP Code
```php
$variable %= 'value'
$variableName %= 'value'
```
#### Public Properties
@ -874,7 +874,7 @@ $variable %= 'value'
#### Example PHP Code
```php
$variable *= 'value'
$variableName *= 'value'
```
#### Public Properties
@ -891,7 +891,7 @@ $variable *= 'value'
#### Example PHP Code
```php
$variable += 'value'
$variableName += 'value'
```
#### Public Properties
@ -908,7 +908,7 @@ $variable += 'value'
#### Example PHP Code
```php
$variable **= 'value'
$variableName **= 'value'
```
#### Public Properties
@ -925,7 +925,7 @@ $variable **= 'value'
#### Example PHP Code
```php
$variable <<= 'value'
$variableName <<= 'value'
```
#### Public Properties
@ -942,7 +942,7 @@ $variable <<= 'value'
#### Example PHP Code
```php
$variable >>= 'value'
$variableName >>= 'value'
```
#### Public Properties
@ -1817,7 +1817,7 @@ const SOME_CLASS_CONSTANT = 'default value';
#### Example PHP Code
```php
public function someMethod()
public function methodName()
{
}
```
@ -1928,7 +1928,7 @@ declare(strict_types=1);
```php
do {
} while ($variable);
} while ($variableName);
```
#### Public Properties
@ -1994,7 +1994,7 @@ else {
#### Example PHP Code
```php
$someVariable;
$variableName;
```
#### Public Properties
@ -2251,7 +2251,28 @@ namespace {
#### Example PHP Code
```php
var $property;
public $propertyName;
```
```php
public static $propertyName, $anotherPropertyName;
```
```php
<?php
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\PropertyProperty;
$propertyProperty = new PropertyProperty(new Identifier('propertyName'));
return new Property(Class_::MODIFIER_PUBLIC, [$propertyProperty]);
```
```php
public $propertyName;
```
#### Public Properties
@ -2300,7 +2321,7 @@ return;
#### Example PHP Code
```php
$variable
$variableName
```
#### Public Properties
@ -2333,7 +2354,7 @@ static $static;
#### Example PHP Code
```php
switch ($variable) {
switch ($variableName) {
case 1:
}
```
@ -2404,7 +2425,7 @@ SomeTrait::method as public aliasedMethod;
#### Example PHP Code
```php
SomeTrait::someMethod insteadof overriddenTrait;
SomeTrait::methodName insteadof overriddenTrait;
```
#### Public Properties
@ -2464,7 +2485,7 @@ try {
#### Example PHP Code
```php
unset($variable);
unset($variableName);
```
#### Public Properties
@ -2515,7 +2536,7 @@ use UsedNamespace;
#### Example PHP Code
```php
while ($variable) {
while ($variableName) {
}
```
@ -2535,7 +2556,7 @@ while ($variable) {
#### Example PHP Code
```php
$someVariable
$variableName
```
#### Public Properties
@ -2621,7 +2642,7 @@ identifier
#### Example PHP Code
```php
$someVariable
$variableName
```
#### Public Properties
@ -2642,7 +2663,7 @@ $someVariable
#### Example PHP Code
```php
string|null
string|int
```
#### Public Properties

View File

@ -4861,7 +4861,7 @@ Remove null coalescing operator ??=
### `DowngradeTypedPropertyRector`
- class: [`Rector\DowngradePhp74\Rector\Property\DowngradeTypedPropertyRector`](/rules/downgrade-php74/src/Rector/Property/DowngradeTypedPropertyRector.php)
- [test fixtures](/rules/downgrade-php74/tests/Rector/Property/NoDocBlockDowngradeTypedPropertyRector/Fixture)
- [test fixtures](/rules/downgrade-php74/tests/Rector/Property/DowngradeTypedPropertyRector/Fixture)
Changes property type definition from type definitions to `@var` annotations.

View File

@ -302,7 +302,7 @@ parameters:
- '#Method (.*?) specified in iterable type Symfony\\Component\\Process\\Process#'
- '#Cannot cast PhpParser\\Node\\Expr\\Error\|PhpParser\\Node\\Identifier to string#'
- '#Cognitive complexity for "Rector\\Utils\\DocumentationGenerator\\Command\\DumpNodesCommand\:\:execute\(\)" is \d+, keep it under 9#'
- '#Cognitive complexity for "Rector\\Utils\\NodeDocumentationGenerator\\Command\\DumpNodesCommand\:\:execute\(\)" is \d+, keep it under 9#'
- '#Parameter \#1 \$node of method Rector\\PostRector\\Collector\\NodesToAddCollector\:\:wrapToExpression\(\) expects PhpParser\\Node\\Expr\|PhpParser\\Node\\Stmt, PhpParser\\Node given#'
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$class#'
@ -461,3 +461,5 @@ parameters:
- packages/dynamic-type-analysis/src/Probe/TypeStaticProbe.php # 24
- packages/dynamic-type-analysis/tests/ProbeStorage/StaticInMemoryProbeStorage.php # 14
- src/Testing/PHPUnit/AbstractGenericRectorTestCase.php # 68
- '#(.*?) expects class\-string, string given#'

View File

@ -2,7 +2,7 @@
namespace Rector\CodingStyle\Tests\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector\Fixture;
function some_variables_with_braces($hello, $world)
function VARIABLE_NAMEs_with_braces($hello, $world)
{
return "$hello {$world}!";
}
@ -13,7 +13,7 @@ function some_variables_with_braces($hello, $world)
namespace Rector\CodingStyle\Tests\Rector\Encapsed\WrapEncapsedVariableInCurlyBracesRector\Fixture;
function some_variables_with_braces($hello, $world)
function VARIABLE_NAMEs_with_braces($hello, $world)
{
return "{$hello} {$world}!";
}

View File

@ -11,7 +11,7 @@ use Rector\ChangesReporting\Output\JsonOutputFormatter;
use Rector\Core\Configuration\Configuration;
use Rector\Core\Exception\Configuration\InvalidConfigurationException;
use Rector\DocumentationGenerator\Command\DumpRectorsCommand;
use Rector\Utils\DocumentationGenerator\Command\DumpNodesCommand;
use Rector\Utils\NodeDocumentationGenerator\Command\DumpNodesCommand;
use Symfony\Component\Console\Application as SymfonyApplication;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputDefinition;

View File

@ -13,6 +13,7 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Expression;
use PhpParser\NodeFinder;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -48,12 +49,18 @@ final class BetterNodeFinder
}
/**
* @param string|string[] $type
* @param class-string|class-string[] $type
*/
public function findFirstParentInstanceOf(Node $node, $type): ?Node
{
if (! is_array($type)) {
$type = [$type];
$types = [$type];
} else {
$types = $type;
}
foreach ($types as $singleType) {
$this->ensureIsNodeClass($singleType, __METHOD__, 1);
}
/** @var Node|null $parentNode */
@ -64,7 +71,7 @@ final class BetterNodeFinder
}
do {
if ($this->isTypes($parentNode, $type)) {
if ($this->isTypes($parentNode, $types)) {
return $parentNode;
}
@ -115,6 +122,8 @@ final class BetterNodeFinder
*/
public function findInstanceOf($nodes, string $type): array
{
$this->ensureIsNodeClass($type, __METHOD__, 1);
return $this->nodeFinder->findInstanceOf($nodes, $type);
}
@ -123,6 +132,8 @@ final class BetterNodeFinder
*/
public function findFirstInstanceOf($nodes, string $type): ?Node
{
$this->ensureIsNodeClass($type, __METHOD__, 1);
return $this->nodeFinder->findFirstInstanceOf($nodes, $type);
}
@ -131,6 +142,8 @@ final class BetterNodeFinder
*/
public function hasInstanceOfName($nodes, string $type, string $name): bool
{
$this->ensureIsNodeClass($type, __METHOD__, 1);
return (bool) $this->findInstanceOfName($nodes, $type, $name);
}
@ -152,11 +165,13 @@ final class BetterNodeFinder
/**
* @param Node|Node[] $nodes
* @param string[] $types
* @param class-string[] $types
*/
public function hasInstancesOf($nodes, array $types): bool
{
foreach ($types as $type) {
$this->ensureIsNodeClass($type, __METHOD__, 1);
if ($this->nodeFinder->findFirstInstanceOf($nodes, $type) === null) {
continue;
}
@ -172,6 +187,8 @@ final class BetterNodeFinder
*/
public function findLastInstanceOf($nodes, string $type): ?Node
{
$this->ensureIsNodeClass($type, __METHOD__, 1);
$foundInstances = $this->nodeFinder->findInstanceOf($nodes, $type);
if ($foundInstances === []) {
return null;
@ -281,11 +298,13 @@ final class BetterNodeFinder
}
/**
* @param string[] $types
* @param class-string[] $types
*/
private function isTypes(Node $node, array $types): bool
{
foreach ($types as $type) {
$this->ensureIsNodeClass($type, __METHOD__, 1);
if (is_a($node, $type, true)) {
return true;
}
@ -296,9 +315,12 @@ final class BetterNodeFinder
/**
* @param Node|Node[] $nodes
* @param class-string $type
*/
private function findInstanceOfName($nodes, string $type, string $name): ?Node
{
$this->ensureIsNodeClass($type, __METHOD__, 1);
$foundInstances = $this->nodeFinder->findInstanceOf($nodes, $type);
foreach ($foundInstances as $foundInstance) {
@ -309,4 +331,21 @@ final class BetterNodeFinder
return null;
}
private function ensureIsNodeClass(string $type, string $location, int $argumentPosition): void
{
if (is_a($type, Node::class, true)) {
return;
}
$errorMessage = sprintf(
'Type given to "%s()" method on %d position must be child of "%s". "%s" given.',
$argumentPosition,
$location,
Node::class,
$type
);
throw new ShouldNotHappenException($errorMessage);
}
}

View File

@ -48,7 +48,7 @@ final class SyncAnnotationParserCommand extends Command
protected function configure(): void
{
$this->setName(CommandNaming::classToName(self::class));
$this->setDescription('[DOC] Generate value-preserving DocParser from doctrine/annotation');
$this->setDescription('[DEV] Generate value-preserving DocParser from doctrine/annotation');
$this->addOption(
Option::OPTION_DRY_RUN,

View File

@ -3,6 +3,7 @@
declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\SmartFileSystem\Finder\SmartFinder;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
@ -12,6 +13,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
->autowire()
->autoconfigure();
$services->load('Rector\Utils\DocumentationGenerator\\', __DIR__ . '/../src')
$services->load('Rector\Utils\NodeDocumentationGenerator\\', __DIR__ . '/../src')
->exclude([__DIR__ . '/../src/ValueObject']);
$services->set(SmartFinder::class);
};

View File

@ -0,0 +1,10 @@
<?php
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\PropertyProperty;
$propertyProperty = new PropertyProperty(new Identifier('propertyName'));
return new Property(Class_::MODIFIER_PUBLIC, [$propertyProperty]);

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace Rector\Utils\NodeDocumentationGenerator\Category;
use Nette\Utils\Strings;
final class CategoryResolver
{
public function resolveCategoryByNodeClass(string $nodeClass): string
{
if (Strings::contains($nodeClass, '\\Scalar\\')) {
return 'Scalar nodes';
}
if (Strings::contains($nodeClass, '\\Expr\\')) {
return 'Expressions';
}
if (Strings::contains($nodeClass, '\\Stmt\\')) {
return 'Statements';
}
return 'Various';
}
}

View File

@ -2,9 +2,8 @@
declare(strict_types=1);
namespace Rector\Utils\DocumentationGenerator\Command;
namespace Rector\Utils\NodeDocumentationGenerator\Command;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Const_;
@ -104,34 +103,32 @@ use PhpParser\Node\VarLikeIdentifier;
use Rector\Core\Console\Command\AbstractCommand;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Utils\DocumentationGenerator\Node\NodeClassProvider;
use Rector\Utils\DocumentationGenerator\Node\NodeInfoResult;
use Rector\Utils\DocumentationGenerator\OutputFormatter\MarkdownDumpNodesOutputFormatter;
use Rector\Utils\DocumentationGenerator\ValueObject\NodeInfo;
use Rector\Utils\NodeDocumentationGenerator\Category\CategoryResolver;
use Rector\Utils\NodeDocumentationGenerator\Node\NodeInfoCollector;
use Rector\Utils\NodeDocumentationGenerator\OutputFormatter\MarkdownDumpNodesOutputFormatter;
use Rector\Utils\NodeDocumentationGenerator\RobotLoader\NodeClassProvider;
use Rector\Utils\NodeDocumentationGenerator\ValueObject\NodeCodeSample;
use Rector\Utils\NodeDocumentationGenerator\ValueObject\NodeInfo;
use ReflectionClass;
use ReflectionMethod;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symplify\PackageBuilder\Console\Command\CommandNaming;
use Symplify\PackageBuilder\Console\ShellCode;
use Symplify\SmartFileSystem\Finder\SmartFinder;
final class DumpNodesCommand extends AbstractCommand
{
/**
* @var string
*/
private const VARIABLE = 'variable';
private const VARIABLE_NAME = 'variableName';
/**
* @var string
*/
private const VALUE = 'value';
/**
* @var string
*/
private const SOME_VARIABLE = 'someVariable';
/**
* @var string
*/
@ -140,12 +137,12 @@ final class DumpNodesCommand extends AbstractCommand
/**
* @var string
*/
private const SOME_CLASS = 'SomeClass';
private const SOME_CLASS = 'SomeClassName';
/**
* @var string
*/
private const SOME_METHOD = 'someMethod';
private const SOME_METHOD = 'methodName';
/**
* @var BetterStandardPrinter
@ -158,7 +155,7 @@ final class DumpNodesCommand extends AbstractCommand
private $nodeClassProvider;
/**
* @var NodeInfoResult
* @var NodeInfoCollector
*/
private $nodeInfoResult;
@ -167,16 +164,30 @@ final class DumpNodesCommand extends AbstractCommand
*/
private $markdownDumpNodesOutputFormatter;
/**
* @var CategoryResolver
*/
private $categoryResolver;
/**
* @var SmartFinder
*/
private $smartFinder;
public function __construct(
BetterStandardPrinter $betterStandardPrinter,
MarkdownDumpNodesOutputFormatter $markdownDumpNodesOutputFormatter,
NodeClassProvider $nodeClassProvider,
NodeInfoResult $nodeInfoResult
NodeInfoCollector $nodeInfoResult,
CategoryResolver $categoryResolver,
SmartFinder $smartFinder
) {
$this->betterStandardPrinter = $betterStandardPrinter;
$this->nodeClassProvider = $nodeClassProvider;
$this->nodeInfoResult = $nodeInfoResult;
$this->markdownDumpNodesOutputFormatter = $markdownDumpNodesOutputFormatter;
$this->categoryResolver = $categoryResolver;
$this->smartFinder = $smartFinder;
parent::__construct();
}
@ -212,38 +223,36 @@ final class DumpNodesCommand extends AbstractCommand
$node->expr = new LNumber(1);
}
$category = $this->resolveCategoryByNodeClass($nodeClass);
$this->nodeInfoResult->addNodeInfo($category, new NodeInfo(
$nodeClass,
$this->betterStandardPrinter->print($node),
false
));
$category = $this->categoryResolver->resolveCategoryByNodeClass($nodeClass);
$nodeInfo = new NodeInfo($nodeClass, $this->createCodeSamples($node), false);
$this->nodeInfoResult->addNodeInfo($category, $nodeInfo);
} elseif (is_a($nodeClass, BinaryOp::class, true)) {
$node = new $nodeClass(new LNumber(1), new String_('a'));
$this->nodeInfoResult->addNodeInfo(BinaryOp::class, new NodeInfo(
$nodeClass,
$this->betterStandardPrinter->print($node),
$this->createCodeSamples($node),
true
));
} elseif (is_a($nodeClass, AssignOp::class, true)) {
$node = new $nodeClass(new Variable(self::VARIABLE), new String_(self::VALUE));
$node = new $nodeClass(new Variable(self::VARIABLE_NAME), new String_(self::VALUE));
$this->nodeInfoResult->addNodeInfo(AssignOp::class, new NodeInfo(
$nodeClass,
$this->betterStandardPrinter->print($node),
$this->createCodeSamples($node),
true
));
} elseif (is_a($nodeClass, Cast::class, true)) {
$node = new $nodeClass(new Variable(self::VALUE));
$this->nodeInfoResult->addNodeInfo(Cast::class, new NodeInfo(
$nodeClass,
$this->betterStandardPrinter->print($node),
$this->createCodeSamples($node),
true
));
} elseif (is_a($nodeClass, Name::class, true)) {
$node = new $nodeClass('name');
$this->nodeInfoResult->addNodeInfo(Name::class, new NodeInfo(
$nodeClass,
$this->betterStandardPrinter->print($node),
$this->createCodeSamples($node),
true
));
} else {
@ -252,10 +261,12 @@ final class DumpNodesCommand extends AbstractCommand
}
$useUseNode = new UseUse(new Name('UsedNamespace'));
$someVariableNode = new Variable(self::SOME_VARIABLE);
$someVariableNode = new Variable(self::VARIABLE_NAME);
$matchArm = new MatchArm([new LNumber(1)], new String_('yes'));
$anotherNode = null;
if ($nodeClass === NullableType::class) {
$node = new NullableType('SomeType');
} elseif ($nodeClass === Const_::class) {
@ -275,25 +286,29 @@ final class DumpNodesCommand extends AbstractCommand
} elseif ($nodeClass === DeclareDeclare::class) {
$node = new DeclareDeclare('strict_types', new LNumber(1));
} elseif ($nodeClass === Do_::class) {
$node = new Do_(new Variable(self::VARIABLE));
$node = new Do_(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === Static_::class) {
$node = new Static_([new StaticVar(new Variable('static'))]);
} elseif ($nodeClass === TraitUse::class) {
$node = new TraitUse([new Name('trait')]);
} elseif ($nodeClass === Switch_::class) {
$node = new Switch_(new Variable(self::VARIABLE), [new Case_(new LNumber(1))]);
$node = new Switch_(new Variable(self::VARIABLE_NAME), [new Case_(new LNumber(1))]);
} elseif ($nodeClass === Match_::class) {
$node = new Match_(new Variable(self::VARIABLE), [$matchArm]);
$node = new Match_(new Variable(self::VARIABLE_NAME), [$matchArm]);
} elseif ($nodeClass === MatchArm::class) {
$node = $matchArm;
} elseif ($nodeClass === Echo_::class) {
$node = new Echo_([new String_('hello')]);
} elseif ($nodeClass === StaticVar::class) {
$node = new StaticVar(new Variable(self::VARIABLE));
$node = new StaticVar(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === Property::class) {
$node = new Property(0, [new PropertyProperty('property')]);
$node = new Property(Class_::MODIFIER_PUBLIC, [new PropertyProperty('propertyName')]);
$anotherNode = new Property(Class_::MODIFIER_STATIC | Class_::MODIFIER_PUBLIC, [
new PropertyProperty('propertyName'),
new PropertyProperty('anotherPropertyName'),
]);
} elseif ($nodeClass === Unset_::class) {
$node = new Unset_([new Variable(self::VARIABLE)]);
$node = new Unset_([new Variable(self::VARIABLE_NAME)]);
} elseif ($nodeClass === Label::class) {
$node = new Label('label');
} elseif ($nodeClass === If_::class) {
@ -324,7 +339,7 @@ final class DumpNodesCommand extends AbstractCommand
} elseif ($nodeClass === UseUse::class) {
$node = $useUseNode;
} elseif ($nodeClass === Expression::class) {
$node = new Expression(new Variable(self::SOME_VARIABLE));
$node = new Expression(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === PropertyProperty::class) {
$node = new PropertyProperty('someProperty');
} elseif ($nodeClass === Global_::class) {
@ -349,19 +364,19 @@ final class DumpNodesCommand extends AbstractCommand
} elseif ($nodeClass === Trait_::class) {
$node = new Trait_('TraitName');
} elseif ($nodeClass === While_::class) {
$node = new While_(new Variable(self::VARIABLE));
$node = new While_(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === Class_::class) {
$node = new Class_(new Identifier('ClassName'));
} elseif ($nodeClass === PostDec::class) {
$node = new PostDec(new Variable(self::SOME_VARIABLE));
$node = new PostDec(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === PreInc::class) {
$node = new PreInc(new Variable(self::SOME_VARIABLE));
$node = new PreInc(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === PostInc::class) {
$node = new PostInc(new Variable(self::SOME_VARIABLE));
$node = new PostInc(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === PreDec::class) {
$node = new PreDec(new Variable(self::SOME_VARIABLE));
$node = new PreDec(new Variable(self::VARIABLE_NAME));
} elseif ($nodeClass === List_::class) {
$node = new List_([new ArrayItem(new Variable(self::SOME_VARIABLE))]);
$node = new List_([new ArrayItem(new Variable(self::VARIABLE_NAME))]);
} elseif ($nodeClass === Instanceof_::class) {
$node = new Instanceof_($someVariableNode, new Name(self::SOME_CLASS));
} elseif ($nodeClass === FuncCall::class) {
@ -379,7 +394,7 @@ final class DumpNodesCommand extends AbstractCommand
} elseif ($nodeClass === PropertyFetch::class) {
$node = new PropertyFetch($someVariableNode, 'propertyName');
} elseif ($nodeClass === Isset_::class) {
$node = new Isset_([new Variable(self::VARIABLE)]);
$node = new Isset_([new Variable(self::VARIABLE_NAME)]);
} elseif ($nodeClass === ArrayDimFetch::class) {
$node = new ArrayDimFetch($someVariableNode, new LNumber(0));
} elseif ($nodeClass === Print_::class) {
@ -430,7 +445,7 @@ final class DumpNodesCommand extends AbstractCommand
} elseif ($nodeClass === Arg::class) {
$node = new Arg($someVariableNode);
} elseif ($nodeClass === UnionType::class) {
$node = new UnionType([new Identifier(self::STRING), new Identifier('null')]);
$node = new UnionType([new Identifier(self::STRING), new Identifier('int')]);
} elseif ($nodeClass === NullsafeMethodCall::class) {
$node = new NullsafeMethodCall($someVariableNode, new Identifier(self::SOME_METHOD));
} elseif ($nodeClass === NullsafePropertyFetch::class) {
@ -445,13 +460,13 @@ final class DumpNodesCommand extends AbstractCommand
));
}
$category = $this->resolveCategoryByNodeClass($nodeClass);
$category = $this->categoryResolver->resolveCategoryByNodeClass($nodeClass);
$codeSamples = $this->createCodeSamples($node, $anotherNode);
$this->nodeInfoResult->addNodeInfo($category, new NodeInfo(
$nodeClass,
trim($this->betterStandardPrinter->print($node)),
true
));
$nodeCodeSamples = $this->findNodeCodeSamples($nodeClass);
$nodeInfo = new NodeInfo($nodeClass, $codeSamples, true, $nodeCodeSamples);
$this->nodeInfoResult->addNodeInfo($category, $nodeInfo);
}
}
@ -460,20 +475,51 @@ final class DumpNodesCommand extends AbstractCommand
return ShellCode::SUCCESS;
}
private function resolveCategoryByNodeClass(string $nodeClass): string
/**
* @return string[]
*/
private function createCodeSamples(Node $node, ?Node $anotherNode = null): array
{
if (Strings::contains($nodeClass, '\\Scalar\\')) {
return 'Scalar nodes';
$codeSamples = [$this->printAndTrim($node)];
if ($anotherNode !== null) {
$codeSamples[] = $this->printAndTrim($anotherNode);
}
if (Strings::contains($nodeClass, '\\Expr\\')) {
return 'Expressions';
return $codeSamples;
}
private function printAndTrim(Node $node): string
{
return trim($this->betterStandardPrinter->print($node));
}
/**
* @todo decouple to NodeCodeSampleFinder service
* @param class-string $nodeClass
*/
private function findNodeCodeSamples(string $nodeClass): array
{
// @todo run just once at start
$snippetFileInfos = $this->smartFinder->find([__DIR__ . '/../../snippet'], '*.php.inc');
$nodeCodeSamples = [];
foreach ($snippetFileInfos as $fileInfo) {
$node = include $fileInfo->getRealPath();
if (! $node instanceof Node) {
$message = sprintf('Snippet "%s" must return a node object', $fileInfo->getPathname());
throw new ShouldNotHappenException($message);
}
if (! is_a($node, $nodeClass, true)) {
continue;
}
$printedContent = $this->betterStandardPrinter->print($node);
$nodeCodeSamples[] = new NodeCodeSample($fileInfo->getContents(), $printedContent);
}
if (Strings::contains($nodeClass, '\\Stmt\\')) {
return 'Statements';
}
return 'Various';
return $nodeCodeSamples;
}
}

View File

@ -2,11 +2,11 @@
declare(strict_types=1);
namespace Rector\Utils\DocumentationGenerator\Node;
namespace Rector\Utils\NodeDocumentationGenerator\Node;
use Rector\Utils\DocumentationGenerator\ValueObject\NodeInfo;
use Rector\Utils\NodeDocumentationGenerator\ValueObject\NodeInfo;
final class NodeInfoResult
final class NodeInfoCollector
{
/**
* @var NodeInfo[][]

View File

@ -2,11 +2,12 @@
declare(strict_types=1);
namespace Rector\Utils\DocumentationGenerator\OutputFormatter;
namespace Rector\Utils\NodeDocumentationGenerator\OutputFormatter;
use Nette\Utils\Strings;
use Rector\Utils\DocumentationGenerator\Node\NodeInfoResult;
use Rector\Utils\DocumentationGenerator\ValueObject\NodeInfo;
use Rector\Utils\NodeDocumentationGenerator\Node\NodeInfoCollector;
use Rector\Utils\NodeDocumentationGenerator\ValueObject\NodeCodeSample;
use Rector\Utils\NodeDocumentationGenerator\ValueObject\NodeInfo;
use Symfony\Component\Console\Style\SymfonyStyle;
final class MarkdownDumpNodesOutputFormatter
@ -21,7 +22,7 @@ final class MarkdownDumpNodesOutputFormatter
$this->symfonyStyle = $symfonyStyle;
}
public function format(NodeInfoResult $nodeInfoResult): void
public function format(NodeInfoCollector $nodeInfoResult): void
{
$this->symfonyStyle->writeln('# Node Overview');
$this->symfonyStyle->newLine();
@ -51,7 +52,7 @@ final class MarkdownDumpNodesOutputFormatter
}
}
private function printCategories(NodeInfoResult $nodeInfoResult): void
private function printCategories(NodeInfoCollector $nodeInfoResult): void
{
foreach ($nodeInfoResult->getCategories() as $category) {
$categoryTitle = $this->createCategoryTitle($category);
@ -86,8 +87,13 @@ final class MarkdownDumpNodesOutputFormatter
$this->symfonyStyle->writeln('#### Example PHP Code');
$this->symfonyStyle->newLine();
$message = sprintf('```php%s%s%s```', PHP_EOL, $nodeInfo->getPrintedContent(), PHP_EOL);
$this->symfonyStyle->writeln($message);
foreach ($nodeInfo->getCodeSamples() as $printedSample) {
$this->printPhpSnippet($printedSample);
}
foreach ($nodeInfo->getNodeCodeSamples() as $nodeCodeSample) {
$this->printNodeCodeSample($nodeCodeSample);
}
}
private function printPublicProperties(NodeInfo $nodeInfo): void
@ -104,4 +110,23 @@ final class MarkdownDumpNodesOutputFormatter
$this->symfonyStyle->writeln($publicPropertyInfo);
}
}
private function printPhpSnippet(string $printedContent): void
{
$message = sprintf('```php%s%s%s```', PHP_EOL, $printedContent, PHP_EOL);
$this->symfonyStyle->writeln($message);
}
private function printNodeCodeSample(NodeCodeSample $nodeCodeSample): void
{
$message = sprintf('```php%s%s%s```', PHP_EOL, $nodeCodeSample->getPhpCode(), PHP_EOL);
$this->symfonyStyle->writeln($message);
$this->symfonyStyle->newLine();
$this->symfonyStyle->writeln('↓');
$this->symfonyStyle->newLine();
$message = sprintf('```php%s%s%s```', PHP_EOL, $nodeCodeSample->getPrintedContent(), PHP_EOL);
$this->symfonyStyle->writeln($message);
}
}

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Utils\DocumentationGenerator\Node;
namespace Rector\Utils\NodeDocumentationGenerator\RobotLoader;
use Nette\Loaders\RobotLoader;

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Rector\Utils\NodeDocumentationGenerator\ValueObject;
final class NodeCodeSample
{
/**
* @var string
*/
private $phpCode;
/**
* @var string
*/
private $printedContent;
public function __construct(string $phpCode, string $printedContent)
{
$this->phpCode = trim($phpCode);
$this->printedContent = trim($printedContent);
}
public function getPhpCode(): string
{
return $this->phpCode;
}
public function getPrintedContent(): string
{
return $this->printedContent;
}
}

View File

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Rector\Utils\DocumentationGenerator\ValueObject;
namespace Rector\Utils\NodeDocumentationGenerator\ValueObject;
use ReflectionClass;
@ -13,11 +13,6 @@ final class NodeInfo
*/
private $class;
/**
* @var string
*/
private $printedContent;
/**
* @var bool
*/
@ -28,11 +23,29 @@ final class NodeInfo
*/
private $publicPropertyInfos = [];
public function __construct(string $class, string $printedContent, bool $hasRequiredArguments)
{
/**
* @var string[]
*/
private $codeSamples = [];
/**
* @var NodeCodeSample[]
*/
private $nodeCodeSamples;
/**
* @param string[] $codeSamples
* @param NodeCodeSample[] $nodeCodeSamples
*/
public function __construct(
string $class,
array $codeSamples,
bool $hasRequiredArguments,
array $nodeCodeSamples = []
) {
$this->class = $class;
$this->printedContent = $printedContent;
$this->hasRequiredArguments = $hasRequiredArguments;
$this->codeSamples = $codeSamples;
$reflectionClass = new ReflectionClass($class);
foreach ($reflectionClass->getProperties() as $reflectionProperty) {
@ -42,6 +55,7 @@ final class NodeInfo
$this->publicPropertyInfos[] = ' * `$' . $reflectionProperty->name . '` - `' . $reflectionProperty->getDocComment() . '`';
}
$this->nodeCodeSamples = $nodeCodeSamples;
}
public function getClass(): string
@ -49,9 +63,12 @@ final class NodeInfo
return $this->class;
}
public function getPrintedContent(): string
/**
* @return string[]
*/
public function getCodeSamples(): array
{
return $this->printedContent;
return $this->codeSamples;
}
public function hasRequiredArguments(): bool
@ -71,4 +88,12 @@ final class NodeInfo
{
return $this->publicPropertyInfos;
}
/**
* @return NodeCodeSample[]
*/
public function getNodeCodeSamples(): array
{
return $this->nodeCodeSamples;
}
}

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace Rector\NodeDocumentationGenerator\Tests\RobotLoader;
use Rector\Core\HttpKernel\RectorKernel;
use Rector\Utils\NodeDocumentationGenerator\RobotLoader\NodeClassProvider;
use Symplify\PackageBuilder\Tests\AbstractKernelTestCase;
final class NodeClassProviderTest extends AbstractKernelTestCase
{
/**
* @var NodeClassProvider
*/
private $nodeClassProvider;
protected function setUp(): void
{
self::bootKernel(RectorKernel::class);
$this->nodeClassProvider = self::$container->get(NodeClassProvider::class);
}
public function test(): void
{
$nodeClasses = $this->nodeClassProvider->getNodeClasses();
$this->assertGreaterThan(100, $nodeClasses);
}
}