Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[PropertyInfo] Incorrect handling of pseudo-types #44455

Copy link
Copy link
Closed
@EmilMassey

Description

@EmilMassey
Issue body actions

Symfony version(s) affected

4.x, 5.x, 6.0

Description

Since static-analysis tools like PHPStan or Psalm became more popular, it is not uncommon to see usage of pseudo-type like:

/** @var non-empty-string */
public $foo;

Some pseudo-types are currently supported (see #43916 introducing list type) but others are not. We can add support for popular custom types used by PHPStan or phpDocumentor (see #44451) but there will always be less common pseudo-types which we are not aware of.

Handling of these cases is inconsistent between extractors and PhpDocExtractor has a bug where the first character of the pseudo-type is trimmed. That one bug is quite easy to fix, but I believe handling of custom, unknown types is overall broken and we should decide how we want to handle them.

How to reproduce

Tested on v6.0.0 tag:

class TestClass {
    /** @var non-empty-string */
    public $foo;

    /** @var some-other-custom-type */
    public $bar;
}

$extractor = new \Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor();
$fooType = $extractor->getTypes(TestClass::class, 'foo'); // $builtinType: object, $class: on-empty-string (first character trimmed)
$barType = $extractor->getTypes(TestClass::class, 'bar'); // NULL

$extractor = new \Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor();
$fooType = $extractor->getTypes(TestClass::class, 'foo'); // $builtinType: object, $class: \non-empty-string (backslash prepended)
$barType = $extractor->getTypes(TestClass::class, 'bar'); // $builtinType: object, $class: \some-other-custom-type

Possible Solution

Expected result

  • pseudo-types shouldn't be automatically treated as objects
  • if the type cannot be correctly mapped to built-in type, getType() should return null or throw an exception
  • or the developer should be informed it is a pseudo-type and decide what to do with doctype
  • the doctype shouldn't be modified and returned as-is (i.e. some-other-custom-type and not \some-other-custom-type)
  • it would be perfect if the results were consistent between both extractors

Additional Context

The first character is trimmed due to bug in \Symfony\Component\PropertyInfo\Util\PhpDocTypeHelper. I believe there's assumption that the $docType is FQCN with backslash prefix but in case of /** @var non-empty-string */ it is passed as-is to the function.

// src/Symfony/Component/PropertyInfo/Util/PhpDocTypeHelper.php

  // $docType: non-empty-string

    private function getPhpTypeAndClass(string $docType): array
    {
        // ...

        return ['object', substr($docType, 1)]; // substr to strip the namespace's `\`-prefix
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.