1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix resolution of same-namespaced classes

This commit is contained in:
Matthew Brown 2018-01-07 12:38:01 -05:00
parent 05d2c3dcb8
commit dc053e699b
19 changed files with 193 additions and 43 deletions

View File

@ -1453,17 +1453,20 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$param_name,
!$docblock_only && $project_checker->php_major_version >= 7
? $inferred_return_type->toPhpString(
$this->source->getNamespace(),
$this->source->getAliasedClassesFlipped(),
$this->source->getFQCLN(),
$project_checker->php_major_version,
$project_checker->php_minor_version
) : null,
$inferred_return_type->toNamespacedString(
$this->source->getNamespace(),
$this->source->getAliasedClassesFlipped(),
$this->source->getFQCLN(),
false
),
$inferred_return_type->toNamespacedString(
$this->source->getNamespace(),
$this->source->getAliasedClassesFlipped(),
$this->source->getFQCLN(),
true
@ -1491,17 +1494,20 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
$manipulator->setReturnType(
!$docblock_only && $project_checker->php_major_version >= 7
? $inferred_return_type->toPhpString(
$this->source->getNamespace(),
$this->source->getAliasedClassesFlipped(),
$this->source->getFQCLN(),
$project_checker->php_major_version,
$project_checker->php_minor_version
) : null,
$inferred_return_type->toNamespacedString(
$this->source->getNamespace(),
$this->source->getAliasedClassesFlipped(),
$this->source->getFQCLN(),
false
),
$inferred_return_type->toNamespacedString(
$this->source->getNamespace(),
$this->source->getAliasedClassesFlipped(),
$this->source->getFQCLN(),
true

View File

@ -240,18 +240,20 @@ abstract class Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param bool $use_phpdoc_format
*
* @return string
*/
public function toNamespacedString(array $aliased_classes, $this_class, $use_phpdoc_format)
public function toNamespacedString($namespace, array $aliased_classes, $this_class, $use_phpdoc_format)
{
return $this->getKey();
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -259,7 +261,13 @@ abstract class Atomic
*
* @return ?string
*/
abstract public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version);
abstract public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
);
/**
* @return bool

View File

@ -22,13 +22,14 @@ trait GenericTrait
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param bool $use_phpdoc_format
*
* @return string
*/
public function toNamespacedString(array $aliased_classes, $this_class, $use_phpdoc_format)
public function toNamespacedString($namespace, array $aliased_classes, $this_class, $use_phpdoc_format)
{
if ($use_phpdoc_format) {
if ($this->value !== 'array') {
@ -41,7 +42,7 @@ trait GenericTrait
return $this->value;
}
$value_type_string = $value_type->toNamespacedString($aliased_classes, $this_class, true);
$value_type_string = $value_type->toNamespacedString($namespace, $aliased_classes, $this_class, true);
if (count($value_type->types) > 1) {
return '(' . $value_type_string . ')[]';
@ -58,8 +59,8 @@ trait GenericTrait
/**
* @return string
*/
function (Union $type_param) use ($aliased_classes, $this_class) {
return $type_param->toNamespacedString($aliased_classes, $this_class, false);
function (Union $type_param) use ($namespace, $aliased_classes, $this_class) {
return $type_param->toNamespacedString($namespace, $aliased_classes, $this_class, false);
},
$this->type_params
)

View File

@ -44,16 +44,22 @@ class ObjectLike extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param bool $use_phpdoc_format
*
* @return string
*/
public function toNamespacedString(array $aliased_classes, $this_class, $use_phpdoc_format)
public function toNamespacedString($namespace, array $aliased_classes, $this_class, $use_phpdoc_format)
{
if ($use_phpdoc_format) {
return $this->getGenericArrayType()->toNamespacedString($aliased_classes, $this_class, $use_phpdoc_format);
return $this->getGenericArrayType()->toNamespacedString(
$namespace,
$aliased_classes,
$this_class,
$use_phpdoc_format
);
}
return 'array{' .
@ -66,8 +72,14 @@ class ObjectLike extends \Psalm\Type\Atomic
*
* @return string
*/
function ($name, Union $type) use ($aliased_classes, $this_class, $use_phpdoc_format) {
function ($name, Union $type) use (
$namespace,
$aliased_classes,
$this_class,
$use_phpdoc_format
) {
return $name . ':' . $type->toNamespacedString(
$namespace,
$aliased_classes,
$this_class,
$use_phpdoc_format
@ -81,6 +93,7 @@ class ObjectLike extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -88,7 +101,7 @@ class ObjectLike extends \Psalm\Type\Atomic
*
* @return string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
public function toPhpString($namespace, array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
return $this->getKey();
}

View File

@ -4,6 +4,7 @@ namespace Psalm\Type\Atomic;
abstract class Scalar extends \Psalm\Type\Atomic
{
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -11,8 +12,13 @@ abstract class Scalar extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return $php_major_version >= 7 ? $this->getKey() : null;
}

View File

@ -29,6 +29,7 @@ class TArray extends \Psalm\Type\Atomic implements Generic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -36,8 +37,13 @@ class TArray extends \Psalm\Type\Atomic implements Generic
*
* @return string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namesapce,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return $this->getKey();
}

View File

@ -17,6 +17,7 @@ class TBool extends Scalar
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TBool extends Scalar
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return $php_major_version >= 7 ? 'bool' : null;
}
}

View File

@ -17,6 +17,7 @@ class TCallable extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TCallable extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}

View File

@ -17,6 +17,7 @@ class TEmpty extends Scalar
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TEmpty extends Scalar
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}
}

View File

@ -17,6 +17,7 @@ class TMixed extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TMixed extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}

View File

@ -45,13 +45,14 @@ class TNamedObject extends Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param bool $use_phpdoc_format
*
* @return string
*/
public function toNamespacedString(array $aliased_classes, $this_class, $use_phpdoc_format)
public function toNamespacedString($namespace, array $aliased_classes, $this_class, $use_phpdoc_format)
{
if ($this->value === $this_class) {
$class_parts = explode('\\', $this_class);
@ -60,6 +61,13 @@ class TNamedObject extends Atomic
return array_pop($class_parts);
}
if ($namespace && preg_match('/^' . preg_quote($namespace) . '/i', $this->value)) {
$class_parts = explode('\\', $this->value);
/** @var string */
return array_pop($class_parts);
}
if (isset($aliased_classes[strtolower($this->value)])) {
return $aliased_classes[strtolower($this->value)];
}
@ -68,6 +76,7 @@ class TNamedObject extends Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -75,9 +84,14 @@ class TNamedObject extends Atomic
*
* @return string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
return $this->toNamespacedString($aliased_classes, $this_class, false);
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return $this->toNamespacedString($namespace, $aliased_classes, $this_class, false);
}
public function canBeFullyExpressedInPhp()

View File

@ -17,6 +17,7 @@ class TNull extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TNull extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}

View File

@ -17,6 +17,7 @@ class TNumeric extends Scalar
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TNumeric extends Scalar
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}
}

View File

@ -17,6 +17,7 @@ class TObject extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TObject extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return $php_major_version >= 7 && $php_minor_version >= 2 ? $this->getKey() : null;
}

View File

@ -17,6 +17,7 @@ class TResource extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TResource extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}

View File

@ -17,6 +17,7 @@ class TScalar extends Scalar
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TScalar extends Scalar
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return null;
}

View File

@ -17,6 +17,7 @@ class TVoid extends \Psalm\Type\Atomic
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -24,8 +25,13 @@ class TVoid extends \Psalm\Type\Atomic
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
return $php_major_version >= 7 && $php_minor_version >= 1 ? $this->getKey() : null;
}

View File

@ -89,13 +89,14 @@ class Union
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param bool $use_phpdoc_format
*
* @return string
*/
public function toNamespacedString(array $aliased_classes, $this_class, $use_phpdoc_format)
public function toNamespacedString($namespace, array $aliased_classes, $this_class, $use_phpdoc_format)
{
return implode(
'|',
@ -103,8 +104,8 @@ class Union
/**
* @return string
*/
function (Atomic $type) use ($aliased_classes, $this_class, $use_phpdoc_format) {
return $type->toNamespacedString($aliased_classes, $this_class, $use_phpdoc_format);
function (Atomic $type) use ($namespace, $aliased_classes, $this_class, $use_phpdoc_format) {
return $type->toNamespacedString($namespace, $aliased_classes, $this_class, $use_phpdoc_format);
},
$this->types
)
@ -112,6 +113,7 @@ class Union
}
/**
* @param string|null $namespace
* @param array<string> $aliased_classes
* @param string|null $this_class
* @param int $php_major_version
@ -119,8 +121,13 @@ class Union
*
* @return ?string
*/
public function toPhpString(array $aliased_classes, $this_class, $php_major_version, $php_minor_version)
{
public function toPhpString(
$namespace,
array $aliased_classes,
$this_class,
$php_major_version,
$php_minor_version
) {
$nullable = false;
if (count($this->types) > 2
@ -145,6 +152,7 @@ class Union
$atomic_type = array_values($types)[0];
$atomic_type_string = $atomic_type->toPhpString(
$namespace,
$aliased_classes,
$this_class,
$php_major_version,

View File

@ -293,6 +293,34 @@ class FileManipulationTest extends TestCase
'7.0',
['MismatchingDocblockParamType'],
],
'fixNamespacedMismatchingDocblockParamType70' => [
'<?php
namespace Foo\Bar {
class A {
/**
* @param \B $b
*/
function foo(B $b) : string {
return "hello";
}
}
class B {}
}',
'<?php
namespace Foo\Bar {
class A {
/**
* @param B $b
*/
function foo(B $b) : string {
return "hello";
}
}
class B {}
}',
'7.0',
['MismatchingDocblockParamType'],
],
'useUnqualifierPlugin' => [
'<?php
namespace A\B\C {