mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
parent
d93906243d
commit
fb9f20f4b8
@ -203,6 +203,7 @@
|
||||
<xs:element name="PossiblyUndefinedVariable" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyUnusedMethod" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyUnusedParam" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PossiblyUnusedProperty" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="PropertyNotSetInConstructor" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="RawObjectIteration" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="RedundantCondition" type="IssueHandlerType" minOccurs="0" />
|
||||
@ -233,6 +234,7 @@
|
||||
<xs:element name="UnevaluatedCode" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="UnusedVariable" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="UnusedParam" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="UnusedProperty" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="UnusedClass" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="UnusedMethod" type="IssueHandlerType" minOccurs="0" />
|
||||
</xs:choice>
|
||||
|
12
psalm.xml
12
psalm.xml
@ -45,6 +45,18 @@
|
||||
</errorLevel>
|
||||
</UnusedClass>
|
||||
|
||||
<UnusedProperty>
|
||||
<errorLevel type="info">
|
||||
<file name="src/Psalm/FileManipulation/FunctionDocblockManipulator.php" />
|
||||
</errorLevel>
|
||||
</UnusedProperty>
|
||||
|
||||
<PossiblyUnusedProperty>
|
||||
<errorLevel type="info">
|
||||
<file name="src/Psalm/Storage/FunctionLikeStorage.php" />
|
||||
</errorLevel>
|
||||
</PossiblyUnusedProperty>
|
||||
|
||||
<PossiblyUnusedMethod>
|
||||
<errorLevel type="suppress">
|
||||
<directory name="tests" />
|
||||
|
@ -88,11 +88,6 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
|
||||
*/
|
||||
protected $fq_class_name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $has_custom_get = false;
|
||||
|
||||
/**
|
||||
* The parent class
|
||||
*
|
||||
@ -100,16 +95,6 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
|
||||
*/
|
||||
protected $parent_fq_class_name;
|
||||
|
||||
/**
|
||||
* @var array<string, MethodChecker>
|
||||
*/
|
||||
protected $method_checkers = [];
|
||||
|
||||
/**
|
||||
* @var array<string, MethodChecker>
|
||||
*/
|
||||
protected $property_types = [];
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, string>>|null
|
||||
*/
|
||||
@ -1552,8 +1537,11 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function propertyExists(ProjectChecker $project_checker, $property_id)
|
||||
{
|
||||
public static function propertyExists(
|
||||
ProjectChecker $project_checker,
|
||||
$property_id,
|
||||
CodeLocation $code_location = null
|
||||
) {
|
||||
// remove trailing backslash if it exists
|
||||
$property_id = preg_replace('/^\\\\/', '', $property_id);
|
||||
|
||||
@ -1562,6 +1550,20 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
|
||||
$class_storage = $project_checker->classlike_storage_provider->get($fq_class_name);
|
||||
|
||||
if (isset($class_storage->declaring_property_ids[$property_name])) {
|
||||
if ($project_checker->collect_references && $code_location) {
|
||||
$declaring_property_id = $class_storage->declaring_property_ids[$property_name];
|
||||
list($declaring_property_class, $declaring_property_name) = explode('::$', $declaring_property_id);
|
||||
|
||||
$declaring_class_storage = $project_checker->classlike_storage_provider->get($declaring_property_class);
|
||||
$declaring_property_storage = $declaring_class_storage->properties[$declaring_property_name];
|
||||
|
||||
if ($declaring_property_storage->referencing_locations === null) {
|
||||
$declaring_property_storage->referencing_locations = [];
|
||||
}
|
||||
|
||||
$declaring_property_storage->referencing_locations[$code_location->file_path][] = $code_location;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -48,16 +48,6 @@ class FileChecker extends SourceChecker implements StatementsSource
|
||||
*/
|
||||
protected $namespace_aliased_classes_flipped = [];
|
||||
|
||||
/**
|
||||
* @var array<int, \PhpParser\Node\Stmt>
|
||||
*/
|
||||
protected $preloaded_statements = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $show_notices = true;
|
||||
|
||||
/**
|
||||
* @var array<string, ClassLikeChecker>
|
||||
*/
|
||||
@ -73,16 +63,6 @@ class FileChecker extends SourceChecker implements StatementsSource
|
||||
*/
|
||||
protected $function_checkers = [];
|
||||
|
||||
/**
|
||||
* @var array<int, NamespaceChecker>
|
||||
*/
|
||||
protected $namespace_checkers = [];
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $included_file_paths = [];
|
||||
|
||||
/**
|
||||
* @var ?Context
|
||||
*/
|
||||
|
@ -59,11 +59,6 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
*/
|
||||
protected $is_static = false;
|
||||
|
||||
/**
|
||||
* @var StatementsChecker|null
|
||||
*/
|
||||
protected $statements_checker;
|
||||
|
||||
/**
|
||||
* @var StatementsSource
|
||||
*/
|
||||
@ -259,11 +254,6 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
|
||||
$statements_checker = new StatementsChecker($this);
|
||||
|
||||
// this increases memory, so only do it if running under this flag
|
||||
if ($project_checker->infer_types_from_usage) {
|
||||
$this->statements_checker = $statements_checker;
|
||||
}
|
||||
|
||||
$template_types = $storage->template_types;
|
||||
|
||||
if ($class_storage && $class_storage->template_types) {
|
||||
@ -439,14 +429,7 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
[],
|
||||
false
|
||||
);
|
||||
} elseif (!$this->function instanceof Closure) {
|
||||
$fleshed_out_return_type = ExpressionChecker::fleshOutType(
|
||||
$project_checker,
|
||||
$storage->return_type,
|
||||
$context->self,
|
||||
$cased_method_id
|
||||
);
|
||||
|
||||
} else {
|
||||
$fleshed_out_signature_type = ExpressionChecker::fleshOutType(
|
||||
$project_checker,
|
||||
$storage->signature_return_type,
|
||||
@ -454,38 +437,54 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
$cased_method_id
|
||||
);
|
||||
|
||||
if (!TypeChecker::isContainedBy(
|
||||
$project_checker,
|
||||
$fleshed_out_return_type,
|
||||
$fleshed_out_signature_type
|
||||
)
|
||||
) {
|
||||
if ($project_checker->alter_code
|
||||
&& isset($project_checker->getIssuesToFix()['MismatchingDocblockReturnType'])
|
||||
) {
|
||||
$this->addOrUpdateReturnType($project_checker, $storage->signature_return_type);
|
||||
$fleshed_out_signature_type->check(
|
||||
$this,
|
||||
$storage->signature_return_type_location ?: $storage->return_type_location,
|
||||
$storage->suppressed_issues,
|
||||
[],
|
||||
false
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (IssueBuffer::accepts(
|
||||
new MismatchingDocblockReturnType(
|
||||
'Docblock has incorrect return type \'' . $storage->return_type .
|
||||
'\', should be \'' . $storage->signature_return_type . '\'',
|
||||
$storage->return_type_location
|
||||
),
|
||||
$storage->suppressed_issues
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$storage->signature_return_type->check(
|
||||
$this,
|
||||
$storage->return_type_location,
|
||||
$storage->suppressed_issues,
|
||||
[],
|
||||
false
|
||||
if (!$this->function instanceof Closure) {
|
||||
$fleshed_out_return_type = ExpressionChecker::fleshOutType(
|
||||
$project_checker,
|
||||
$storage->return_type,
|
||||
$context->self,
|
||||
$cased_method_id
|
||||
);
|
||||
|
||||
$fleshed_out_signature_type = ExpressionChecker::fleshOutType(
|
||||
$project_checker,
|
||||
$storage->signature_return_type,
|
||||
$context->self,
|
||||
$cased_method_id
|
||||
);
|
||||
|
||||
if (!TypeChecker::isContainedBy(
|
||||
$project_checker,
|
||||
$fleshed_out_return_type,
|
||||
$fleshed_out_signature_type
|
||||
)
|
||||
) {
|
||||
if ($project_checker->alter_code
|
||||
&& isset($project_checker->getIssuesToFix()['MismatchingDocblockReturnType'])
|
||||
) {
|
||||
$this->addOrUpdateReturnType($project_checker, $storage->signature_return_type);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (IssueBuffer::accepts(
|
||||
new MismatchingDocblockReturnType(
|
||||
'Docblock has incorrect return type \'' . $storage->return_type .
|
||||
'\', should be \'' . $storage->signature_return_type . '\'',
|
||||
$storage->return_type_location
|
||||
),
|
||||
$storage->suppressed_issues
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +177,6 @@ class MethodChecker extends FunctionLikeChecker
|
||||
$declaring_class = $method->getDeclaringClass();
|
||||
|
||||
$storage->is_static = $method->isStatic();
|
||||
$storage->namespace = $declaring_class->getNamespaceName();
|
||||
$class_storage->declaring_method_ids[$method_name] =
|
||||
$declaring_class->name . '::' . strtolower((string)$method->getName());
|
||||
|
||||
|
@ -26,21 +26,6 @@ class NamespaceChecker extends SourceChecker implements StatementsSource
|
||||
*/
|
||||
private $namespace_name;
|
||||
|
||||
/**
|
||||
* @var array<int, FunctionChecker>
|
||||
*/
|
||||
public $function_checkers = [];
|
||||
|
||||
/**
|
||||
* @var array<int, ClassChecker>
|
||||
*/
|
||||
public $class_checkers = [];
|
||||
|
||||
/**
|
||||
* @var array<int, ClassChecker>
|
||||
*/
|
||||
public $interface_checkers = [];
|
||||
|
||||
/**
|
||||
* A lookup table for public namespace constants
|
||||
*
|
||||
|
@ -9,8 +9,10 @@ use Psalm\FileManipulation\FunctionDocblockManipulator;
|
||||
use Psalm\Issue\CircularReference;
|
||||
use Psalm\Issue\PossiblyUnusedMethod;
|
||||
use Psalm\Issue\PossiblyUnusedParam;
|
||||
use Psalm\Issue\PossiblyUnusedProperty;
|
||||
use Psalm\Issue\UnusedClass;
|
||||
use Psalm\Issue\UnusedMethod;
|
||||
use Psalm\Issue\UnusedProperty;
|
||||
use Psalm\IssueBuffer;
|
||||
use Psalm\Provider\ClassLikeStorageProvider;
|
||||
use Psalm\Provider\FileProvider;
|
||||
@ -181,11 +183,6 @@ class ProjectChecker
|
||||
*/
|
||||
private $scanned_files = [];
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
*/
|
||||
private $visited_classes = [];
|
||||
|
||||
/**
|
||||
* @var array<string, FileChecker>
|
||||
*/
|
||||
@ -1274,6 +1271,37 @@ class ProjectChecker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($classlike_storage->properties as $property_name => $property_storage) {
|
||||
if (($property_storage->referencing_locations === null
|
||||
|| count($property_storage->referencing_locations) === 0)
|
||||
&& (substr($property_name, 0, 2) !== '__' || $property_name === '__construct')
|
||||
&& $property_storage->location
|
||||
) {
|
||||
$property_id = $classlike_storage->name . '::$' . $property_name;
|
||||
|
||||
if ($property_storage->visibility === ClassLikeChecker::VISIBILITY_PUBLIC) {
|
||||
if (IssueBuffer::accepts(
|
||||
new PossiblyUnusedProperty(
|
||||
'Cannot find public calls to property ' . $property_id,
|
||||
$property_storage->location
|
||||
),
|
||||
$classlike_storage->suppressed_issues
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
} elseif (!isset($classlike_storage->declaring_method_ids['__get'])) {
|
||||
if (IssueBuffer::accepts(
|
||||
new UnusedProperty(
|
||||
'Property ' . $property_id . ' is never used',
|
||||
$property_storage->location
|
||||
)
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +89,6 @@ class IfChecker
|
||||
$context->inside_conditional = false;
|
||||
|
||||
$if_scope = new IfScope();
|
||||
$if_scope->has_elseifs = count($stmt->elseifs) > 0;
|
||||
|
||||
$if_context = clone $context;
|
||||
|
||||
|
@ -80,6 +80,8 @@ class FetchChecker
|
||||
return false;
|
||||
}
|
||||
|
||||
$project_checker = $statements_checker->getFileChecker()->project_checker;
|
||||
|
||||
$stmt_var_id = ExpressionChecker::getVarId(
|
||||
$stmt->var,
|
||||
$statements_checker->getFQCLN(),
|
||||
@ -98,6 +100,25 @@ class FetchChecker
|
||||
// we don't need to check anything
|
||||
$stmt->inferredType = $context->vars_in_scope[$var_id];
|
||||
|
||||
if ($context->collect_references
|
||||
&& isset($stmt->var->inferredType)
|
||||
&& $stmt->var->inferredType->hasObjectType()
|
||||
&& is_string($stmt->name)
|
||||
) {
|
||||
// log the appearance
|
||||
foreach ($stmt->var->inferredType->getTypes() as $lhs_type_part) {
|
||||
if ($lhs_type_part instanceof TNamedObject) {
|
||||
$property_id = $lhs_type_part->value . '::$' . $stmt->name;
|
||||
|
||||
ClassLikeChecker::propertyExists(
|
||||
$project_checker,
|
||||
$property_id,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -208,8 +229,6 @@ class FetchChecker
|
||||
continue;
|
||||
}
|
||||
|
||||
$project_checker = $statements_checker->getFileChecker()->project_checker;
|
||||
|
||||
if (!ClassChecker::classExists($project_checker, $lhs_type_part->value)) {
|
||||
if (InterfaceChecker::interfaceExists($project_checker, $lhs_type_part->value)) {
|
||||
if (IssueBuffer::accepts(
|
||||
@ -260,7 +279,12 @@ class FetchChecker
|
||||
}
|
||||
}
|
||||
|
||||
if (!ClassLikeChecker::propertyExists($project_checker, $property_id)) {
|
||||
if (!ClassLikeChecker::propertyExists(
|
||||
$project_checker,
|
||||
$property_id,
|
||||
$context->collect_references ? new CodeLocation($statements_checker->getSource(), $stmt) : null
|
||||
)
|
||||
) {
|
||||
if ($context->inside_isset) {
|
||||
return;
|
||||
}
|
||||
@ -699,16 +723,30 @@ class FetchChecker
|
||||
$statements_checker
|
||||
);
|
||||
|
||||
$property_id = $fq_class_name . '::$' . $stmt->name;
|
||||
|
||||
if ($var_id && $context->hasVariable($var_id)) {
|
||||
// we don't need to check anything
|
||||
$stmt->inferredType = $context->vars_in_scope[$var_id];
|
||||
|
||||
if ($context->collect_references) {
|
||||
// log the appearance
|
||||
ClassLikeChecker::propertyExists(
|
||||
$project_checker,
|
||||
$property_id,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$property_id = $fq_class_name . '::$' . $stmt->name;
|
||||
|
||||
if (!ClassLikeChecker::propertyExists($project_checker, $property_id)) {
|
||||
if (!ClassLikeChecker::propertyExists(
|
||||
$project_checker,
|
||||
$property_id,
|
||||
$context->collect_references ? new CodeLocation($statements_checker->getSource(), $stmt) : null
|
||||
)
|
||||
) {
|
||||
if (IssueBuffer::accepts(
|
||||
new UndefinedPropertyFetch(
|
||||
'Static property ' . $property_id . ' is not defined',
|
||||
|
@ -110,13 +110,6 @@ class Config
|
||||
*/
|
||||
protected $base_dir;
|
||||
|
||||
/**
|
||||
* The path to this config file
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $file_path;
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
@ -186,9 +179,6 @@ class Config
|
||||
*/
|
||||
private $plugins = [];
|
||||
|
||||
/** @var array<string, bool> */
|
||||
private $predefined_classlikes = [];
|
||||
|
||||
/** @var array<string, mixed> */
|
||||
private $predefined_constants;
|
||||
|
||||
@ -238,8 +228,6 @@ class Config
|
||||
{
|
||||
$config = new static();
|
||||
|
||||
$config->file_path = $file_path;
|
||||
|
||||
$config->base_dir = $base_dir;
|
||||
|
||||
$schema_path = dirname(dirname(__DIR__)) . '/config.xsd';
|
||||
|
@ -21,11 +21,6 @@ class FileFilter
|
||||
*/
|
||||
protected $files_lowercase = [];
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $patterns = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
6
src/Psalm/Issue/PossiblyUnusedProperty.php
Normal file
6
src/Psalm/Issue/PossiblyUnusedProperty.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class PossiblyUnusedProperty extends CodeIssue
|
||||
{
|
||||
}
|
6
src/Psalm/Issue/UnusedProperty.php
Normal file
6
src/Psalm/Issue/UnusedProperty.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class UnusedProperty extends CodeIssue
|
||||
{
|
||||
}
|
@ -46,11 +46,6 @@ class IfScope
|
||||
*/
|
||||
public $negatable_if_types = null;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $has_elseifs;
|
||||
|
||||
/**
|
||||
* @var array<int, Clause>
|
||||
*/
|
||||
|
@ -32,11 +32,6 @@ class ClassLikeStorage
|
||||
*/
|
||||
public $populated = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $reflected = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
@ -62,11 +57,6 @@ class ClassLikeStorage
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
public $aliased_classes;
|
||||
|
||||
/**
|
||||
* Is this class user-defined
|
||||
*
|
||||
|
@ -22,11 +22,6 @@ class FunctionLikeStorage
|
||||
*/
|
||||
public $param_types = [];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $namespace;
|
||||
|
||||
/**
|
||||
* @var Type\Union|null
|
||||
*/
|
||||
|
@ -10,16 +10,6 @@ class MethodStorage extends FunctionLikeStorage
|
||||
*/
|
||||
public $is_static;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $reflected;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $registered;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
@ -45,4 +45,9 @@ class PropertyStorage
|
||||
* @var bool
|
||||
*/
|
||||
public $deprecated = false;
|
||||
|
||||
/**
|
||||
* @var array<string, array<int, CodeLocation>>|null
|
||||
*/
|
||||
public $referencing_locations;
|
||||
}
|
||||
|
@ -6,11 +6,6 @@ use Psalm\Type\Union;
|
||||
|
||||
class Fn extends TNamedObject
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $value = 'Closure';
|
||||
|
||||
/**
|
||||
* @var array<int, FunctionLikeParameter>
|
||||
*/
|
||||
@ -30,6 +25,7 @@ class Fn extends TNamedObject
|
||||
*/
|
||||
public function __construct($value, array $params, Union $return_type)
|
||||
{
|
||||
$this->value = 'Closure';
|
||||
$this->params = $params;
|
||||
$this->return_type = $return_type;
|
||||
}
|
||||
|
@ -41,11 +41,6 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
|
||||
/** @var Aliases */
|
||||
protected $file_aliases;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $in_classlike = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
|
@ -6,9 +6,6 @@ use Psalm\Config;
|
||||
|
||||
class ConfigTest extends TestCase
|
||||
{
|
||||
/** @var \PhpParser\Parser */
|
||||
protected static $parser;
|
||||
|
||||
/** @var TestConfig */
|
||||
protected static $config;
|
||||
|
||||
|
@ -7,9 +7,6 @@ use Psalm\Checker\ProjectChecker;
|
||||
|
||||
class TestCase extends BaseTestCase
|
||||
{
|
||||
/** @var \PhpParser\Parser */
|
||||
protected static $parser;
|
||||
|
||||
/** @var TestConfig */
|
||||
protected static $config;
|
||||
|
||||
|
@ -958,6 +958,15 @@ class TypeTest extends TestCase
|
||||
public function providerFileCheckerInvalidCodeParse()
|
||||
{
|
||||
return [
|
||||
'possiblyUndefinedVariable' => [
|
||||
'<?php
|
||||
if (rand(0, 1)) {
|
||||
$a = 5;
|
||||
}
|
||||
|
||||
echo $a;',
|
||||
'error_message' => 'PossiblyUndefinedGlobalVariable',
|
||||
],
|
||||
'nullableMethodCall' => [
|
||||
'<?php
|
||||
class A {
|
||||
|
@ -156,11 +156,16 @@ class UnusedCodeTest extends TestCase
|
||||
public function modifyFoo(string $value) : void {
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
public function getFoo() : string {
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
|
||||
$m = new A();
|
||||
$m->foo("value");
|
||||
$m->modifyFoo("value2");',
|
||||
$m->modifyFoo("value2");
|
||||
echo $m->getFoo();',
|
||||
],
|
||||
'usedTraitMethod' => [
|
||||
'<?php
|
||||
|
Loading…
Reference in New Issue
Block a user