mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Fix handling of class const types
This commit is contained in:
parent
36ac342496
commit
20c66f693e
@ -78,7 +78,7 @@ trait CanAlias
|
|||||||
$file_manipulations[] = new \Psalm\FileManipulation(
|
$file_manipulations[] = new \Psalm\FileManipulation(
|
||||||
(int) $use->getAttribute('startFilePos'),
|
(int) $use->getAttribute('startFilePos'),
|
||||||
(int) $use->getAttribute('endFilePos') + 1,
|
(int) $use->getAttribute('endFilePos') + 1,
|
||||||
$new_fq_class_name
|
$new_fq_class_name . ($use->alias ? ' as ' . $use_alias : '')
|
||||||
);
|
);
|
||||||
|
|
||||||
FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
|
FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
|
||||||
|
@ -435,7 +435,8 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer implements Statements
|
|||||||
$storage->return_type,
|
$storage->return_type,
|
||||||
$context->self,
|
$context->self,
|
||||||
$context->self,
|
$context->self,
|
||||||
$this->getParentFQCLN()
|
$this->getParentFQCLN(),
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
$codebase->classlikes->handleDocblockTypeInMigration(
|
$codebase->classlikes->handleDocblockTypeInMigration(
|
||||||
@ -458,7 +459,8 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer implements Statements
|
|||||||
$function_param->type,
|
$function_param->type,
|
||||||
$context->self,
|
$context->self,
|
||||||
$context->self,
|
$context->self,
|
||||||
$this->getParentFQCLN()
|
$this->getParentFQCLN(),
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
$codebase->classlikes->handleDocblockTypeInMigration(
|
$codebase->classlikes->handleDocblockTypeInMigration(
|
||||||
|
@ -1001,7 +1001,8 @@ class ExpressionAnalyzer
|
|||||||
Type\Union $return_type,
|
Type\Union $return_type,
|
||||||
?string $self_class,
|
?string $self_class,
|
||||||
$static_class_type,
|
$static_class_type,
|
||||||
?string $parent_class
|
?string $parent_class,
|
||||||
|
bool $evaluate = true
|
||||||
) {
|
) {
|
||||||
$return_type = clone $return_type;
|
$return_type = clone $return_type;
|
||||||
|
|
||||||
@ -1013,7 +1014,8 @@ class ExpressionAnalyzer
|
|||||||
$return_type_part,
|
$return_type_part,
|
||||||
$self_class,
|
$self_class,
|
||||||
$static_class_type,
|
$static_class_type,
|
||||||
$parent_class
|
$parent_class,
|
||||||
|
$evaluate
|
||||||
);
|
);
|
||||||
|
|
||||||
if (is_array($parts)) {
|
if (is_array($parts)) {
|
||||||
@ -1048,7 +1050,8 @@ class ExpressionAnalyzer
|
|||||||
Type\Atomic &$return_type,
|
Type\Atomic &$return_type,
|
||||||
?string $self_class,
|
?string $self_class,
|
||||||
$static_class_type,
|
$static_class_type,
|
||||||
?string $parent_class
|
?string $parent_class,
|
||||||
|
bool $evaluate = true
|
||||||
) {
|
) {
|
||||||
if ($return_type instanceof TNamedObject
|
if ($return_type instanceof TNamedObject
|
||||||
|| $return_type instanceof TTemplateParam
|
|| $return_type instanceof TTemplateParam
|
||||||
@ -1062,7 +1065,8 @@ class ExpressionAnalyzer
|
|||||||
$extra_type,
|
$extra_type,
|
||||||
$self_class,
|
$self_class,
|
||||||
$static_class_type,
|
$static_class_type,
|
||||||
$parent_class
|
$parent_class,
|
||||||
|
$evaluate
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($extra_type instanceof TNamedObject && $extra_type->extra_types) {
|
if ($extra_type instanceof TNamedObject && $extra_type->extra_types) {
|
||||||
@ -1121,7 +1125,7 @@ class ExpressionAnalyzer
|
|||||||
$return_type->fq_classlike_name = $self_class;
|
$return_type->fq_classlike_name = $self_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($codebase->classOrInterfaceExists($return_type->fq_classlike_name)) {
|
if ($evaluate && $codebase->classOrInterfaceExists($return_type->fq_classlike_name)) {
|
||||||
if (strtolower($return_type->const_name) === 'class') {
|
if (strtolower($return_type->const_name) === 'class') {
|
||||||
return new Type\Atomic\TLiteralClassString($return_type->fq_classlike_name);
|
return new Type\Atomic\TLiteralClassString($return_type->fq_classlike_name);
|
||||||
}
|
}
|
||||||
@ -1152,7 +1156,7 @@ class ExpressionAnalyzer
|
|||||||
$return_type->fq_classlike_name = $self_class;
|
$return_type->fq_classlike_name = $self_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($codebase->classOrInterfaceExists($return_type->fq_classlike_name)) {
|
if ($evaluate && $codebase->classOrInterfaceExists($return_type->fq_classlike_name)) {
|
||||||
$class_constants = $codebase->classlikes->getConstantsForClass(
|
$class_constants = $codebase->classlikes->getConstantsForClass(
|
||||||
$return_type->fq_classlike_name,
|
$return_type->fq_classlike_name,
|
||||||
\ReflectionProperty::IS_PRIVATE
|
\ReflectionProperty::IS_PRIVATE
|
||||||
|
@ -1036,11 +1036,20 @@ class ClassLikes
|
|||||||
$uses_flipped = $source->getAliasedClassesFlipped();
|
$uses_flipped = $source->getAliasedClassesFlipped();
|
||||||
$uses_flipped_replaceable = $source->getAliasedClassesFlippedReplaceable();
|
$uses_flipped_replaceable = $source->getAliasedClassesFlippedReplaceable();
|
||||||
|
|
||||||
if (isset($uses_flipped_replaceable[strtolower($fq_class_name)])) {
|
$old_fq_class_name = strtolower($fq_class_name);
|
||||||
unset($uses_flipped_replaceable[strtolower($fq_class_name)]);
|
|
||||||
$new_class_name_parts = explode('\\', $new_fq_class_name);
|
if (isset($uses_flipped_replaceable[$old_fq_class_name])) {
|
||||||
$class_name = end($new_class_name_parts);
|
$alias = $uses_flipped_replaceable[$old_fq_class_name];
|
||||||
$uses_flipped[strtolower($new_fq_class_name)] = $class_name;
|
unset($uses_flipped_replaceable[$old_fq_class_name]);
|
||||||
|
$old_class_name_parts = explode('\\', $old_fq_class_name);
|
||||||
|
$old_class_name = end($old_class_name_parts);
|
||||||
|
if (strtolower($old_class_name) === strtolower($alias)) {
|
||||||
|
$new_class_name_parts = explode('\\', $new_fq_class_name);
|
||||||
|
$new_class_name = end($new_class_name_parts);
|
||||||
|
$uses_flipped[strtolower($new_fq_class_name)] = $new_class_name;
|
||||||
|
} else {
|
||||||
|
$uses_flipped[strtolower($new_fq_class_name)] = $alias;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_manipulations[] = new \Psalm\FileManipulation(
|
$file_manipulations[] = new \Psalm\FileManipulation(
|
||||||
@ -1138,10 +1147,17 @@ class ClassLikes
|
|||||||
$uses_flipped_replaceable = $source->getAliasedClassesFlippedReplaceable();
|
$uses_flipped_replaceable = $source->getAliasedClassesFlippedReplaceable();
|
||||||
|
|
||||||
if (isset($uses_flipped_replaceable[$old_fq_class_name])) {
|
if (isset($uses_flipped_replaceable[$old_fq_class_name])) {
|
||||||
|
$alias = $uses_flipped_replaceable[$old_fq_class_name];
|
||||||
unset($uses_flipped_replaceable[$old_fq_class_name]);
|
unset($uses_flipped_replaceable[$old_fq_class_name]);
|
||||||
$new_class_name_parts = explode('\\', $new_fq_class_name);
|
$old_class_name_parts = explode('\\', $old_fq_class_name);
|
||||||
$class_name = end($new_class_name_parts);
|
$old_class_name = end($old_class_name_parts);
|
||||||
$uses_flipped[strtolower($new_fq_class_name)] = $class_name;
|
if (strtolower($old_class_name) === strtolower($alias)) {
|
||||||
|
$new_class_name_parts = explode('\\', $new_fq_class_name);
|
||||||
|
$new_class_name = end($new_class_name_parts);
|
||||||
|
$uses_flipped[strtolower($new_fq_class_name)] = $new_class_name;
|
||||||
|
} else {
|
||||||
|
$uses_flipped[strtolower($new_fq_class_name)] = $alias;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_manipulations[] = new \Psalm\FileManipulation(
|
$file_manipulations[] = new \Psalm\FileManipulation(
|
||||||
|
@ -812,7 +812,7 @@ abstract class Atomic
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this instanceof TScalarClassConstant) {
|
if ($this instanceof TScalarClassConstant) {
|
||||||
if (strtolower($old) === $new) {
|
if (strtolower($this->fq_classlike_name) === $old) {
|
||||||
$this->fq_classlike_name = $new;
|
$this->fq_classlike_name = $new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,17 +366,19 @@ class ClassMoveTest extends \Psalm\Tests\TestCase
|
|||||||
'A' => 'Foo\Bar\Baz\B',
|
'A' => 'Foo\Bar\Baz\B',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'moveClassDeeperIntoNamespaceAdjustUse' => [
|
'moveClassDeeperIntoNamespaceAdjustUseWithoutAlias' => [
|
||||||
'<?php
|
'<?php
|
||||||
namespace Foo {
|
namespace Foo {
|
||||||
use Bar\Bat;
|
use Bar\Bat;
|
||||||
|
|
||||||
echo Bat::FOO;
|
echo Bat::FOO;
|
||||||
|
echo Bat::FAR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bat $b
|
* @param Bat $b
|
||||||
|
* @param Bat::FOO|Bat::FAR $c
|
||||||
*/
|
*/
|
||||||
function doSomething(Bat $b) : void {}
|
function doSomething(Bat $b, int $c) : void {}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
/** @var ?Bat */
|
/** @var ?Bat */
|
||||||
@ -386,6 +388,7 @@ class ClassMoveTest extends \Psalm\Tests\TestCase
|
|||||||
namespace Bar {
|
namespace Bar {
|
||||||
class Bat {
|
class Bat {
|
||||||
const FOO = 5;
|
const FOO = 5;
|
||||||
|
const FAR = 7;
|
||||||
}
|
}
|
||||||
}',
|
}',
|
||||||
'<?php
|
'<?php
|
||||||
@ -393,11 +396,13 @@ class ClassMoveTest extends \Psalm\Tests\TestCase
|
|||||||
use Bar\Baz\Bahh;
|
use Bar\Baz\Bahh;
|
||||||
|
|
||||||
echo Bahh::FOO;
|
echo Bahh::FOO;
|
||||||
|
echo Bahh::FAR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Bahh $b
|
* @param Bahh $b
|
||||||
|
* @param Bahh::FOO|Bahh::FAR $c
|
||||||
*/
|
*/
|
||||||
function doSomething(Bahh $b) : void {}
|
function doSomething(Bahh $b, int $c) : void {}
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
/** @var null|Bahh */
|
/** @var null|Bahh */
|
||||||
@ -407,6 +412,60 @@ class ClassMoveTest extends \Psalm\Tests\TestCase
|
|||||||
namespace Bar\Baz {
|
namespace Bar\Baz {
|
||||||
class Bahh {
|
class Bahh {
|
||||||
const FOO = 5;
|
const FOO = 5;
|
||||||
|
const FAR = 7;
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
[
|
||||||
|
'Bar\Bat' => 'Bar\Baz\Bahh',
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'moveClassDeeperIntoNamespaceAdjustUseWithAlias' => [
|
||||||
|
'<?php
|
||||||
|
namespace Foo {
|
||||||
|
use Bar\Bat as Kappa;
|
||||||
|
|
||||||
|
echo Kappa::FOO;
|
||||||
|
echo Kappa::FAR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Kappa $b
|
||||||
|
* @param Kappa::FOO|Kappa::FAR $c
|
||||||
|
*/
|
||||||
|
function doSomething(Kappa $b, int $c) : void {}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
/** @var ?Kappa */
|
||||||
|
public $x = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Bar {
|
||||||
|
class Bat {
|
||||||
|
const FOO = 5;
|
||||||
|
const FAR = 7;
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
'<?php
|
||||||
|
namespace Foo {
|
||||||
|
use Bar\Baz\Bahh as Kappa;
|
||||||
|
|
||||||
|
echo Kappa::FOO;
|
||||||
|
echo Kappa::FAR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Kappa $b
|
||||||
|
* @param Kappa::FOO|Kappa::FAR $c
|
||||||
|
*/
|
||||||
|
function doSomething(Kappa $b, int $c) : void {}
|
||||||
|
|
||||||
|
class A {
|
||||||
|
/** @var null|Kappa */
|
||||||
|
public $x = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace Bar\Baz {
|
||||||
|
class Bahh {
|
||||||
|
const FOO = 5;
|
||||||
|
const FAR = 7;
|
||||||
}
|
}
|
||||||
}',
|
}',
|
||||||
[
|
[
|
||||||
|
Loading…
Reference in New Issue
Block a user