Skip to content

Commit

Permalink
PhpdocToPropertyTypeFixer - introduction
Browse files Browse the repository at this point in the history
  • Loading branch information
julienfalque authored and keradus committed May 3, 2021
1 parent 24e9391 commit 0382be5
Show file tree
Hide file tree
Showing 17 changed files with 836 additions and 23 deletions.
67 changes: 67 additions & 0 deletions doc/rules/function_notation/phpdoc_to_property_type.rst
@@ -0,0 +1,67 @@
================================
Rule ``phpdoc_to_property_type``
================================

EXPERIMENTAL: Takes ``@var`` annotation of non-mixed types and adjusts
accordingly the property signature. Requires PHP >= 7.4.

.. warning:: Using this rule is risky.

This rule is EXPERIMENTAL and [1] is not covered with backward compatibility
promise. [2] ``@var`` annotation is mandatory for the fixer to make changes,
signatures of properties without it (no docblock) will not be fixed. [3]
Manual actions might be required for newly typed properties that are read
before initialization.

Configuration
-------------

``scalar_types``
~~~~~~~~~~~~~~~~

Fix also scalar types; may have unexpected behaviour due to PHP bad type
coercion system.

Allowed types: ``bool``

Default value: ``true``

Examples
--------

Example #1
~~~~~~~~~~

*Default* configuration.

.. code-block:: diff
--- Original
+++ New
<?php
class Foo {
/** @var int */
- private $foo;
+ private int $foo;
/** @var \Traversable */
- private $bar;
+ private \Traversable $bar;
}
Example #2
~~~~~~~~~~

With configuration: ``['scalar_types' => false]``.

.. code-block:: diff
--- Original
+++ New
<?php
class Foo {
/** @var int */
private $foo;
/** @var \Traversable */
- private $bar;
+ private \Traversable $bar;
}
2 changes: 1 addition & 1 deletion doc/rules/function_notation/phpdoc_to_return_type.rst
Expand Up @@ -11,7 +11,7 @@ accordingly the function signature. Requires PHP >= 7.0.
promise. [2] ``@return`` annotation is mandatory for the fixer to make
changes, signatures of methods without it (no docblock, inheritdocs) will not
be fixed. [3] Manual actions are required if inherited signatures are not
properly documented. [4] ``@inheritdocs`` support is under construction.
properly documented.

Configuration
-------------
Expand Down
2 changes: 2 additions & 0 deletions doc/rules/index.rst
Expand Up @@ -249,6 +249,8 @@ Function Notation
Adds or removes ``?`` before type declarations for parameters with a default ``null`` value.
- `phpdoc_to_param_type <./function_notation/phpdoc_to_param_type.rst>`_ *(risky)*
EXPERIMENTAL: Takes ``@param`` annotations of non-mixed types and adjusts accordingly the function signature. Requires PHP >= 7.0.
- `phpdoc_to_property_type <./function_notation/phpdoc_to_property_type.rst>`_ *(risky)*
EXPERIMENTAL: Takes ``@var`` annotation of non-mixed types and adjusts accordingly the property signature. Requires PHP >= 7.4.
- `phpdoc_to_return_type <./function_notation/phpdoc_to_return_type.rst>`_ *(risky)*
EXPERIMENTAL: Takes ``@return`` annotation of non-mixed types and adjusts accordingly the function signature. Requires PHP >= 7.0.
- `regular_callable_call <./function_notation/regular_callable_call.rst>`_ *(risky)*
Expand Down
28 changes: 18 additions & 10 deletions src/AbstractPhpdocToTypeDeclarationFixer.php
Expand Up @@ -87,14 +87,11 @@ protected function createConfigurationDefinition()
}

/**
* Find all the annotations of given type in the function's PHPDoc comment.
* @param int $index The index of the function token
*
* @param string $name
* @param int $index The index of the function token
*
* @return Annotation[]
* @return null|int
*/
protected function findAnnotations($name, Tokens $tokens, $index)
protected function findFunctionDocComment(Tokens $tokens, $index)
{
do {
$index = $tokens->getPrevNonWhitespace($index);
Expand All @@ -108,18 +105,29 @@ protected function findAnnotations($name, Tokens $tokens, $index)
T_STATIC,
]));

if (!$tokens[$index]->isGivenKind(T_DOC_COMMENT)) {
return [];
if ($tokens[$index]->isGivenKind(T_DOC_COMMENT)) {
return $index;
}

return null;
}

/**
* @param string $name
* @param int $docCommentIndex
*
* @return Annotation[]
*/
protected function getAnnotationsFromDocComment($name, Tokens $tokens, $docCommentIndex)
{
$namespacesAnalyzer = new NamespacesAnalyzer();
$namespace = $namespacesAnalyzer->getNamespaceAt($tokens, $index);
$namespace = $namespacesAnalyzer->getNamespaceAt($tokens, $docCommentIndex);

$namespaceUsesAnalyzer = new NamespaceUsesAnalyzer();
$namespaceUses = $namespaceUsesAnalyzer->getDeclarationsInNamespace($tokens, $namespace);

$doc = new DocBlock(
$tokens[$index]->getContent(),
$tokens[$docCommentIndex]->getContent(),
$namespace,
$namespaceUses
);
Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/Comment/CommentToPhpdocFixer.php
Expand Up @@ -54,7 +54,7 @@ public function isRisky()
/**
* {@inheritdoc}
*
* Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocInlineTagFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToCommentFixer, PhpdocToParamTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer.
* Must run before GeneralPhpdocAnnotationRemoveFixer, GeneralPhpdocTagRenameFixer, NoBlankLinesAfterPhpdocFixer, NoEmptyPhpdocFixer, NoSuperfluousPhpdocTagsFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocAlignFixer, PhpdocAlignFixer, PhpdocAnnotationWithoutDotFixer, PhpdocInlineTagFixer, PhpdocInlineTagNormalizerFixer, PhpdocLineSpanFixer, PhpdocNoAccessFixer, PhpdocNoAliasTagFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocOrderByValueFixer, PhpdocOrderFixer, PhpdocReturnSelfReferenceFixer, PhpdocSeparationFixer, PhpdocSingleLineVarSpacingFixer, PhpdocSummaryFixer, PhpdocTagCasingFixer, PhpdocTagTypeFixer, PhpdocToCommentFixer, PhpdocToParamTypeFixer, PhpdocToPropertyTypeFixer, PhpdocToReturnTypeFixer, PhpdocTrimConsecutiveBlankLineSeparationFixer, PhpdocTrimFixer, PhpdocTypesOrderFixer, PhpdocVarAnnotationCorrectOrderFixer, PhpdocVarWithoutNameFixer.
* Must run after AlignMultilineCommentFixer.
*/
public function getPriority()
Expand Down
8 changes: 6 additions & 2 deletions src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php
Expand Up @@ -124,9 +124,13 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
continue;
}

$paramTypeAnnotations = $this->findAnnotations('param', $tokens, $index);
$docCommentIndex = $this->findFunctionDocComment($tokens, $index);

foreach ($paramTypeAnnotations as $paramTypeAnnotation) {
if (null === $docCommentIndex) {
continue;
}

foreach ($this->getAnnotationsFromDocComment('param', $tokens, $docCommentIndex) as $paramTypeAnnotation) {
$typeInfo = $this->getCommonTypeFromAnnotation($paramTypeAnnotation, false);

if (null === $typeInfo) {
Expand Down

0 comments on commit 0382be5

Please sign in to comment.