Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PhpdocToParamTypeFixer - fix for breaking PHP syntax for type having reserved name #5006

Merged
merged 1 commit into from Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/AbstractPhpdocToTypeDeclarationFixer.php
@@ -0,0 +1,40 @@
<?php

/*
* This file is part of PHP CS Fixer.
*
* (c) Fabien Potencier <fabien@symfony.com>
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace PhpCsFixer;

use PhpCsFixer\Tokenizer\Tokens;

/**
* @internal
*/
abstract class AbstractPhpdocToTypeDeclarationFixer extends AbstractFixer
{
/**
* @var array<string, bool>
*/
private static $syntaxValidationCache = [];

final protected function isValidSyntax($code)
{
if (!isset(self::$syntaxValidationCache[$code])) {
try {
Tokens::fromCode($code);
self::$syntaxValidationCache[$code] = true;
} catch (\ParseError $e) {
self::$syntaxValidationCache[$code] = false;
}
}

return self::$syntaxValidationCache[$code];
}
}
8 changes: 6 additions & 2 deletions src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php
Expand Up @@ -12,7 +12,7 @@

namespace PhpCsFixer\Fixer\FunctionNotation;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\AbstractPhpdocToTypeDeclarationFixer;
use PhpCsFixer\DocBlock\Annotation;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
Expand All @@ -29,7 +29,7 @@
/**
* @author Jan Gantzert <jan@familie-gantzert.de>
*/
final class PhpdocToParamTypeFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface
final class PhpdocToParamTypeFixer extends AbstractPhpdocToTypeDeclarationFixer implements ConfigurationDefinitionFixerInterface
{
/** @internal */
const CLASS_REGEX = '/^\\\\?[a-zA-Z_\\x7f-\\xff](?:\\\\?[a-zA-Z0-9_\\x7f-\\xff]+)*(?<array>\[\])*$/';
Expand Down Expand Up @@ -263,6 +263,10 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
continue;
}

if (!$this->isValidSyntax(sprintf('<?php function f(%s $x) {}', $paramType))) {
continue;
}

$this->fixFunctionDefinition(
$paramType,
$tokens,
Expand Down
30 changes: 3 additions & 27 deletions src/Fixer/FunctionNotation/PhpdocToReturnTypeFixer.php
Expand Up @@ -12,7 +12,7 @@

namespace PhpCsFixer\Fixer\FunctionNotation;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\AbstractPhpdocToTypeDeclarationFixer;
use PhpCsFixer\DocBlock\Annotation;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
Expand All @@ -29,7 +29,7 @@
/**
* @author Filippo Tessarotto <zoeslam@gmail.com>
*/
final class PhpdocToReturnTypeFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface
final class PhpdocToReturnTypeFixer extends AbstractPhpdocToTypeDeclarationFixer implements ConfigurationDefinitionFixerInterface
{
/**
* @var array<int, array<int, int|string>>
Expand Down Expand Up @@ -75,11 +75,6 @@ final class PhpdocToReturnTypeFixer extends AbstractFixer implements Configurati
*/
private $classRegex = '/^\\\\?[a-zA-Z_\\x7f-\\xff](?:\\\\?[a-zA-Z0-9_\\x7f-\\xff]+)*(?<array>\[\])*$/';

/**
* @var array<string, bool>
*/
private $returnTypeCache = [];

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -256,7 +251,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
continue;
}

if (!$this->isValidType($returnType)) {
if (!$this->isValidSyntax(sprintf('<?php function f():%s {}', $returnType))) {
continue;
}

Expand Down Expand Up @@ -346,23 +341,4 @@ private function findReturnAnnotations(Tokens $tokens, $index)

return $doc->getAnnotationsOfType('return');
}

/**
* @param string $returnType
*
* @return bool
*/
private function isValidType($returnType)
{
if (!\array_key_exists($returnType, $this->returnTypeCache)) {
try {
Tokens::fromCode(sprintf('<?php function f():%s {}', $returnType));
$this->returnTypeCache[$returnType] = true;
} catch (\ParseError $e) {
$this->returnTypeCache[$returnType] = false;
}
}

return $this->returnTypeCache[$returnType];
}
}
7 changes: 7 additions & 0 deletions tests/Fixer/FunctionNotation/PhpdocToParamTypeFixerTest.php
Expand Up @@ -80,6 +80,13 @@ function my_foo() {}
function my_foo2($bar) {}
',
],
'invalid - phpdoc param with keyword' => [
'<?php
/** @param Break $foo */ function foo_break($foo) {}
/** @param __CLASS__ $foo */ function foo_class($foo) {}
/** @param I\Want\To\Break\Free $foo */ function foo_queen($foo) {}
',
],
'non-root class with single int param' => [
'<?php /** @param int $bar */ function my_foo(int $bar) {}',
'<?php /** @param int $bar */ function my_foo($bar) {}',
Expand Down