mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Treat methods of internal or psalm internal classes as internal (#3698)
When both the method and the class are annotated as psalm-internal, but to different namespaces, we consider the method internal to whichever namespace is longer, i.e. the smaller code module. Issue reported at https://github.com/vimeo/psalm/issues/3457
This commit is contained in:
parent
0f727e7607
commit
3f8aa64ee9
@ -68,6 +68,7 @@ use function substr;
|
||||
use function trim;
|
||||
use function preg_split;
|
||||
use php_user_filter;
|
||||
use function strlen;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -2133,6 +2134,12 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
|
||||
|
||||
$doc_comment = $stmt->getDocComment();
|
||||
|
||||
|
||||
if ($class_storage && ! $class_storage->is_trait) {
|
||||
$storage->internal = $class_storage->internal;
|
||||
$storage->psalm_internal = $class_storage->psalm_internal;
|
||||
}
|
||||
|
||||
if (!$doc_comment) {
|
||||
if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod
|
||||
&& $stmt->name->name === '__construct'
|
||||
@ -2190,7 +2197,12 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements PhpParse
|
||||
$storage->internal = true;
|
||||
}
|
||||
|
||||
if ($docblock_info->psalm_internal) {
|
||||
if (null === $class_storage ||
|
||||
null === $class_storage->psalm_internal ||
|
||||
(null !== $docblock_info->psalm_internal &&
|
||||
strlen($docblock_info->psalm_internal) > strlen($class_storage->psalm_internal)
|
||||
)
|
||||
) {
|
||||
$storage->psalm_internal = $docblock_info->psalm_internal;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,30 @@ class InternalAnnotationTest extends TestCase
|
||||
}
|
||||
}',
|
||||
],
|
||||
'internalClassWithInstanceCall' => [
|
||||
'<?php
|
||||
namespace A {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Foo {
|
||||
public function barBar(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getFoo(): Foo {
|
||||
return new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
namespace A\B {
|
||||
class Bat {
|
||||
public function batBat(): void {
|
||||
\A\getFoo()->barBar();
|
||||
}
|
||||
}
|
||||
}',
|
||||
],
|
||||
'internalClassExtendingNamespaceWithStaticCall' => [
|
||||
'<?php
|
||||
namespace A {
|
||||
@ -244,6 +268,31 @@ class InternalAnnotationTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'InternalClass',
|
||||
],
|
||||
'internalClassWithInstanceCall' => [
|
||||
'<?php
|
||||
namespace A {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Foo {
|
||||
public function barBar(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getFoo(): Foo {
|
||||
return new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
namespace B {
|
||||
class Bat {
|
||||
public function batBat(): void {
|
||||
\A\getFoo()->barBar();
|
||||
}
|
||||
}
|
||||
}',
|
||||
'error_message' => 'InternalMethod',
|
||||
],
|
||||
'internalClassWithNew' => [
|
||||
'<?php
|
||||
namespace A {
|
||||
|
@ -64,7 +64,7 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
*/
|
||||
public static function barBar(): void {
|
||||
}
|
||||
|
||||
|
||||
public static function foo(): void {
|
||||
self::barBar();
|
||||
}
|
||||
@ -92,6 +92,31 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
}
|
||||
}',
|
||||
],
|
||||
'internalClassWithInstanceCall' => [
|
||||
'<?php
|
||||
namespace A\B {
|
||||
/**
|
||||
* @internal
|
||||
* @psalm-internal A\B
|
||||
*/
|
||||
class Foo {
|
||||
public function barBar(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getFoo(): Foo {
|
||||
return new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
namespace A\B\C {
|
||||
class Bat {
|
||||
public function batBat(\A\B\Foo $instance): void {
|
||||
\A\B\getFoo()->barBar();
|
||||
}
|
||||
}
|
||||
}',
|
||||
],
|
||||
'internalClassExtendingNamespaceWithStaticCall' => [
|
||||
'<?php
|
||||
namespace A {
|
||||
@ -294,6 +319,32 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'InternalClass',
|
||||
],
|
||||
'internalClassWithInstanceCall' => [
|
||||
'<?php
|
||||
namespace A\B {
|
||||
/**
|
||||
* @internal
|
||||
* @psalm-internal A\B
|
||||
*/
|
||||
class Foo {
|
||||
public function barBar(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function getFoo(): Foo {
|
||||
return new Foo();
|
||||
}
|
||||
}
|
||||
|
||||
namespace A\C {
|
||||
class Bat {
|
||||
public function batBat(): void {
|
||||
\A\B\getFoo()->barBar();
|
||||
}
|
||||
}
|
||||
}',
|
||||
'error_message' => 'The method A\B\Foo::barBar has been marked as internal to A\B',
|
||||
],
|
||||
'internalClassWithNew' => [
|
||||
'<?php
|
||||
namespace A\B {
|
||||
@ -387,10 +438,10 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
'internalPropertyMissingNamespace' => [
|
||||
'<?php
|
||||
class Foo {
|
||||
/**
|
||||
/**
|
||||
* @var int
|
||||
* @internal
|
||||
* @psalm-internal
|
||||
* @psalm-internal
|
||||
*/
|
||||
var $bar;
|
||||
}
|
||||
@ -401,8 +452,8 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
'<?php
|
||||
class Foo {
|
||||
/**
|
||||
* @internal
|
||||
* @psalm-internal
|
||||
* @internal
|
||||
* @psalm-internal
|
||||
*/
|
||||
function Bar(): void {}
|
||||
}
|
||||
@ -429,7 +480,7 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
* @var int
|
||||
* @psalm-internal A\B
|
||||
*/
|
||||
public $foo;
|
||||
public $foo;
|
||||
}
|
||||
}
|
||||
',
|
||||
@ -438,13 +489,13 @@ class PsalmInternalAnnotationTest extends TestCase
|
||||
'internalFunctionMissingInternalAnnotation' => [
|
||||
'<?php
|
||||
namespace A\B {
|
||||
class Foo {
|
||||
class Foo {
|
||||
/**
|
||||
* @psalm-internal A\B
|
||||
*/
|
||||
public function foo()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
',
|
||||
|
Loading…
x
Reference in New Issue
Block a user