Skip to content

PHPCS v4 compatibility bug #1790

@dereuromark

Description

@dereuromark

Bug Report: AnnotationHelper::fixAnnotation Changes Indentation from Spaces to Tabs

When trying to get a sniffer package to v4 compatibility.

Summary

When using AnnotationHelper::fixAnnotation() to modify a PHPDoc annotation in a union type containing an array type hint, the helper changes the indentation of the entire doc comment from spaces to tabs, even when the original file uses spaces.

Environment

  • SlevomatCodingStandard version: 8.23 AND dev-phpcs4 (commit fe765b3)
  • PHP_CodeSniffer version: ^4.0.0
  • PHP version: 8.4.12

Steps to Reproduce

  1. Create a PHP file with space-indented PHPDoc comment:
<?php
class Test {
    /**
     * @return \ArrayObject<string>|int[]
     */
    protected function getArrayObjectOfStringsOrArrayOfInts()
    {
        return $this->foo();
    }
}

Note: The file uses 4 spaces for indentation (not tabs).

  1. Use AnnotationHelper::fixAnnotation() to replace int[] with array<int> in the union type.

  2. Apply the fix using FixerHelper::change().

Expected Behavior

The fixed doc comment should preserve the original indentation style (spaces):

    /**
     * @return \ArrayObject<string>|array<int>
     */

Actual Behavior

The fixed doc comment is changed to use tabs:

    /**
	 * @return \ArrayObject<string>|array<int>
	 */

Note the second and third lines now use tabs (shown as ^I in cat -A output).

Code Path

The issue occurs when:

  1. AnnotationHelper::fixAnnotation() is called to fix a union type annotation
  2. The fixed content is applied using FixerHelper::change()

Example code from our sniff:

$fixedDocComment = AnnotationHelper::fixAnnotation(
    $parsedDocComment,
    $annotation,
    $unionTypeNode,
    $genericTypeNode,
);

// Later...
$phpcsFile->fixer->beginChangeset();
FixerHelper::change(
    $phpcsFile,
    $parsedDocComment->getOpenPointer(),
    $parsedDocComment->getClosePointer(),
    $fixedDocComment,
);
$phpcsFile->fixer->endChangeset();

Impact

This causes issues in codebases that enforce space-only indentation, as the fixer changes the indentation style of doc comments it modifies.

Possible Solution

AnnotationHelper::fixAnnotation() should detect and preserve the original indentation style of the doc comment, or provide an option to specify the desired indentation style.

Test Case

Input file (with spaces):

    /**
     * @return \ArrayObject<string>|int[]
     */

After running through AnnotationHelper::fixAnnotation + FixerHelper::change:

    /**
	 * @return \ArrayObject<string>|array<int>
	 */

The indentation characters have changed from spaces to tabs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions