mirror of
https://github.com/danog/psalm.git
synced 2024-12-12 01:09:38 +01:00
commit
b29737f2b1
@ -95,7 +95,7 @@ class Codebase
|
||||
/**
|
||||
* @var null|'always'|'auto'
|
||||
*/
|
||||
public $find_unused_code = null;
|
||||
public $find_unused_code;
|
||||
|
||||
/**
|
||||
* @var FileProvider
|
||||
@ -179,7 +179,7 @@ class Codebase
|
||||
/**
|
||||
* @var ?Internal\Codebase\TaintFlowGraph
|
||||
*/
|
||||
public $taint_flow_graph = null;
|
||||
public $taint_flow_graph;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
@ -614,7 +614,7 @@ class Codebase
|
||||
|
||||
public function getStubbedConstantType(string $const_id): ?Type\Union
|
||||
{
|
||||
return isset(self::$stubbed_constants[$const_id]) ? self::$stubbed_constants[$const_id] : null;
|
||||
return self::$stubbed_constants[$const_id] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1614,7 +1614,7 @@ class Codebase
|
||||
$insertion_text = Type::getStringFromFQCLN(
|
||||
$fq_class_name,
|
||||
$aliases && $aliases->namespace ? $aliases->namespace : null,
|
||||
$aliases ? $aliases->uses_flipped : [],
|
||||
$aliases->uses_flipped ?? [],
|
||||
null
|
||||
);
|
||||
|
||||
|
@ -55,7 +55,6 @@ use function getcwd;
|
||||
use function glob;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use function is_a;
|
||||
use function is_dir;
|
||||
use function is_file;
|
||||
@ -80,7 +79,6 @@ use function strlen;
|
||||
use function strpos;
|
||||
use function strrpos;
|
||||
use function strtolower;
|
||||
use function strtr;
|
||||
use function substr;
|
||||
use function substr_count;
|
||||
use function sys_get_temp_dir;
|
||||
@ -182,7 +180,7 @@ class Config
|
||||
*
|
||||
* @var bool|null
|
||||
*/
|
||||
public $load_xdebug_stub = null;
|
||||
public $load_xdebug_stub;
|
||||
|
||||
/**
|
||||
* The directory to store PHP Parser (and other) caches
|
||||
@ -288,7 +286,7 @@ class Config
|
||||
/**
|
||||
* @var ?bool
|
||||
*/
|
||||
public $show_mixed_issues = null;
|
||||
public $show_mixed_issues;
|
||||
|
||||
/** @var bool */
|
||||
public $strict_binary_operands = false;
|
||||
@ -501,7 +499,7 @@ class Config
|
||||
public $hash = '';
|
||||
|
||||
/** @var string|null */
|
||||
public $error_baseline = null;
|
||||
public $error_baseline;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
@ -978,7 +976,7 @@ class Config
|
||||
}
|
||||
|
||||
if (isset($config_xml['maxStringLength'])) {
|
||||
$attribute_text = intval($config_xml['maxStringLength']);
|
||||
$attribute_text = (int)$config_xml['maxStringLength'];
|
||||
$config->max_string_length = $attribute_text;
|
||||
}
|
||||
|
||||
@ -2115,7 +2113,7 @@ class Config
|
||||
$psr4_prefixes = $this->composer_class_loader->getPrefixesPsr4();
|
||||
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
|
||||
$logicalPathPsr4 = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
|
||||
|
||||
$candidate_path = null;
|
||||
|
||||
@ -2200,11 +2198,7 @@ class Config
|
||||
|
||||
public function getPhpVersion(): ?string
|
||||
{
|
||||
if (isset($this->configured_php_version)) {
|
||||
return $this->configured_php_version;
|
||||
}
|
||||
|
||||
return $this->getPHPVersionFromComposerJson();
|
||||
return $this->configured_php_version ?? $this->getPHPVersionFromComposerJson();
|
||||
}
|
||||
|
||||
private function setBooleanAttribute(string $name, bool $value): void
|
||||
|
@ -76,13 +76,11 @@ class Creator
|
||||
);
|
||||
}
|
||||
|
||||
$template = str_replace(
|
||||
return str_replace(
|
||||
'errorLevel="1"',
|
||||
'errorLevel="' . $level . '"',
|
||||
$template
|
||||
);
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
public static function createBareConfig(
|
||||
|
@ -11,7 +11,7 @@ class ProjectFileFilter extends FileFilter
|
||||
/**
|
||||
* @var ProjectFileFilter|null
|
||||
*/
|
||||
private $file_filter = null;
|
||||
private $file_filter;
|
||||
|
||||
/**
|
||||
* @return static
|
||||
|
@ -103,7 +103,7 @@ class Context
|
||||
/**
|
||||
* @var null|CodeLocation
|
||||
*/
|
||||
public $include_location = null;
|
||||
public $include_location;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
@ -194,7 +194,7 @@ class Context
|
||||
*
|
||||
* @var array<string, bool>|null
|
||||
*/
|
||||
public $initialized_methods = null;
|
||||
public $initialized_methods;
|
||||
|
||||
/**
|
||||
* @var array<string, Type\Union>
|
||||
@ -290,27 +290,27 @@ class Context
|
||||
/**
|
||||
* @var Internal\Scope\LoopScope|null
|
||||
*/
|
||||
public $loop_scope = null;
|
||||
public $loop_scope;
|
||||
|
||||
/**
|
||||
* @var Internal\Scope\CaseScope|null
|
||||
*/
|
||||
public $case_scope = null;
|
||||
public $case_scope;
|
||||
|
||||
/**
|
||||
* @var Internal\Scope\FinallyScope|null
|
||||
*/
|
||||
public $finally_scope = null;
|
||||
public $finally_scope;
|
||||
|
||||
/**
|
||||
* @var Context|null
|
||||
*/
|
||||
public $if_context = null;
|
||||
public $if_context;
|
||||
|
||||
/**
|
||||
* @var \Psalm\Internal\Scope\IfScope|null
|
||||
*/
|
||||
public $if_scope = null;
|
||||
public $if_scope;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
@ -418,7 +418,7 @@ class Context
|
||||
? $end_context->vars_in_scope[$var_id]
|
||||
: null;
|
||||
|
||||
$existing_type = isset($this->vars_in_scope[$var_id]) ? $this->vars_in_scope[$var_id] : null;
|
||||
$existing_type = $this->vars_in_scope[$var_id] ?? null;
|
||||
|
||||
if (!$existing_type) {
|
||||
if ($new_type) {
|
||||
|
@ -16,6 +16,7 @@ use function rtrim;
|
||||
use function str_repeat;
|
||||
use function str_replace;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strspn;
|
||||
use function substr;
|
||||
use function trim;
|
||||
@ -156,7 +157,7 @@ class DocComment
|
||||
$docblock = preg_replace('/^\s*\n/', '', $docblock);
|
||||
|
||||
foreach ($special as $special_key => $_) {
|
||||
if (substr($special_key, 0, 6) === 'psalm-') {
|
||||
if (strpos($special_key, 'psalm-') === 0) {
|
||||
$special_key = substr($special_key, 6);
|
||||
|
||||
if (!in_array(
|
||||
@ -186,7 +187,7 @@ class DocComment
|
||||
);
|
||||
|
||||
foreach ($parsed_docblock->tags as $special_key => $_) {
|
||||
if (substr($special_key, 0, 6) === 'psalm-') {
|
||||
if (strpos($special_key, 'psalm-') === 0) {
|
||||
$special_key = substr($special_key, 6);
|
||||
|
||||
if (!in_array(
|
||||
|
@ -55,7 +55,7 @@ class FileManipulation
|
||||
$indentation = substr($existing_contents, $newline_pos, $this->start - $newline_pos);
|
||||
|
||||
if (trim($indentation) === '') {
|
||||
$this->insertion_text = $this->insertion_text . $indentation;
|
||||
$this->insertion_text .= $indentation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ trait CanAlias
|
||||
|
||||
foreach ($stmt->uses as $use) {
|
||||
$use_path = implode('\\', $use->name->parts);
|
||||
$use_alias = $use->alias ? $use->alias->name : $use->name->getLast();
|
||||
$use_alias = $use->alias->name ?? $use->name->getLast();
|
||||
|
||||
switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $stmt->type) {
|
||||
case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
|
||||
@ -107,7 +107,7 @@ trait CanAlias
|
||||
|
||||
foreach ($stmt->uses as $use) {
|
||||
$use_path = $use_prefix . '\\' . implode('\\', $use->name->parts);
|
||||
$use_alias = $use->alias ? $use->alias->name : $use->name->getLast();
|
||||
$use_alias = $use->alias->name ?? $use->name->getLast();
|
||||
|
||||
switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $stmt->type) {
|
||||
case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
|
||||
|
@ -368,7 +368,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
$this->fq_class_name . ', defined abstract in ' . $declaring_class_name,
|
||||
new CodeLocation(
|
||||
$this,
|
||||
$class->name ? $class->name : $class,
|
||||
$class->name ?? $class,
|
||||
$class_context->include_location,
|
||||
true
|
||||
)
|
||||
@ -984,7 +984,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
return;
|
||||
}
|
||||
|
||||
$fq_class_name = $class_context->self ? $class_context->self : $this->fq_class_name;
|
||||
$fq_class_name = $class_context->self ?: $this->fq_class_name;
|
||||
$fq_class_name_lc = strtolower($fq_class_name);
|
||||
|
||||
$included_file_path = $this->getFilePath();
|
||||
@ -1913,9 +1913,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
);
|
||||
}
|
||||
|
||||
$overridden_method_ids = isset($class_storage->overridden_method_ids[strtolower($stmt->name->name)])
|
||||
? $class_storage->overridden_method_ids[strtolower($stmt->name->name)]
|
||||
: [];
|
||||
$overridden_method_ids = $class_storage->overridden_method_ids[strtolower($stmt->name->name)] ?? [];
|
||||
|
||||
if (!$return_type
|
||||
&& !$class_storage->is_interface
|
||||
@ -2276,7 +2274,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
|
||||
$code_location = new CodeLocation(
|
||||
$this,
|
||||
$class->name ? $class->name : $class,
|
||||
$class->name ?? $class,
|
||||
$class_context->include_location,
|
||||
true
|
||||
);
|
||||
@ -2488,7 +2486,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
$code_location = new CodeLocation(
|
||||
$this,
|
||||
$extended_class,
|
||||
$class_context ? $class_context->include_location : null,
|
||||
$class_context->include_location ?? null,
|
||||
true
|
||||
);
|
||||
|
||||
@ -2592,7 +2590,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
$code_location = new CodeLocation(
|
||||
$this,
|
||||
$class->name ?: $class,
|
||||
$class_context ? $class_context->include_location : null,
|
||||
$class_context->include_location ?? null,
|
||||
true
|
||||
);
|
||||
|
||||
|
@ -454,7 +454,7 @@ abstract class ClassLikeAnalyzer extends SourceAnalyzer
|
||||
|
||||
public function getClassName(): ?string
|
||||
{
|
||||
return $this->class->name ? $this->class->name->name : null;
|
||||
return $this->class->name->name ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -580,22 +580,17 @@ abstract class ClassLikeAnalyzer extends SourceAnalyzer
|
||||
return $emit_issues ? null : true;
|
||||
|
||||
case self::VISIBILITY_PRIVATE:
|
||||
if (!$context->self || $appearing_property_class !== $context->self) {
|
||||
if ($emit_issues && IssueBuffer::accepts(
|
||||
new InaccessibleProperty(
|
||||
'Cannot access private property ' . $property_id . ' from context ' . $context->self,
|
||||
$code_location
|
||||
),
|
||||
$suppressed_issues
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
|
||||
return null;
|
||||
if ($emit_issues && IssueBuffer::accepts(
|
||||
new InaccessibleProperty(
|
||||
'Cannot access private property ' . $property_id . ' from context ' . $context->self,
|
||||
$code_location
|
||||
),
|
||||
$suppressed_issues
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
|
||||
return $emit_issues ? null : true;
|
||||
|
||||
return null;
|
||||
case self::VISIBILITY_PROTECTED:
|
||||
if (!$context->self) {
|
||||
if ($emit_issues && IssueBuffer::accepts(
|
||||
|
@ -41,8 +41,8 @@ use Psalm\Type;
|
||||
use function array_diff;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -109,7 +109,7 @@ class ReturnTypeAnalyzer
|
||||
$is_to_string = $function instanceof ClassMethod && strtolower($function->name->name) === '__tostring';
|
||||
|
||||
if ($function instanceof ClassMethod
|
||||
&& substr($function->name->name, 0, 2) === '__'
|
||||
&& strpos($function->name->name, '__') === 0
|
||||
&& !$is_to_string
|
||||
&& !$return_type
|
||||
) {
|
||||
@ -170,7 +170,7 @@ class ReturnTypeAnalyzer
|
||||
|
||||
$function_always_exits = $control_actions === [ScopeAnalyzer::ACTION_END];
|
||||
|
||||
$function_returns_implicitly = !!array_diff(
|
||||
$function_returns_implicitly = (bool)array_diff(
|
||||
$control_actions,
|
||||
[ScopeAnalyzer::ACTION_END, ScopeAnalyzer::ACTION_RETURN]
|
||||
);
|
||||
@ -748,8 +748,8 @@ class ReturnTypeAnalyzer
|
||||
$fleshed_out_return_type = \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$storage->return_type,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$classlike_storage->name ?? null,
|
||||
$classlike_storage->name ?? null,
|
||||
$parent_class
|
||||
);
|
||||
|
||||
@ -770,8 +770,8 @@ class ReturnTypeAnalyzer
|
||||
$fleshed_out_signature_type = \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$storage->signature_return_type,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$classlike_storage->name ?? null,
|
||||
$classlike_storage->name ?? null,
|
||||
$parent_class
|
||||
);
|
||||
|
||||
@ -792,8 +792,8 @@ class ReturnTypeAnalyzer
|
||||
$fleshed_out_return_type = \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$storage->return_type,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$classlike_storage->name ?? null,
|
||||
$classlike_storage->name ?? null,
|
||||
$parent_class,
|
||||
true,
|
||||
true
|
||||
@ -936,7 +936,7 @@ class ReturnTypeAnalyzer
|
||||
true
|
||||
),
|
||||
$inferred_return_type->canBeFullyExpressedInPhp($codebase->php_major_version, $codebase->php_minor_version),
|
||||
$function_like_storage ? $function_like_storage->return_type_description : null
|
||||
$function_like_storage->return_type_description ?? null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1624,16 +1624,6 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getFQCLN(): ?string
|
||||
{
|
||||
return $this->source->getFQCLN();
|
||||
}
|
||||
|
||||
public function getClassName(): ?string
|
||||
{
|
||||
return $this->source->getClassName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array<string, Type\Union>>|null
|
||||
*/
|
||||
@ -1647,16 +1637,6 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer
|
||||
return $this->storage->template_types;
|
||||
}
|
||||
|
||||
public function getParentFQCLN(): ?string
|
||||
{
|
||||
return $this->source->getParentFQCLN();
|
||||
}
|
||||
|
||||
public function getNodeTypeProvider() : \Psalm\NodeTypeProvider
|
||||
{
|
||||
return $this->source->getNodeTypeProvider();
|
||||
}
|
||||
|
||||
public function isStatic(): bool
|
||||
{
|
||||
return $this->is_static;
|
||||
|
@ -26,8 +26,8 @@ use Psalm\Storage\MethodStorage;
|
||||
use Psalm\Type;
|
||||
|
||||
use function in_array;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
class MethodComparator
|
||||
{
|
||||
@ -412,7 +412,7 @@ class MethodComparator
|
||||
&& $implementer_classlike_storage->user_defined
|
||||
&& $implementer_param->location
|
||||
&& $guide_method_storage->cased_name
|
||||
&& substr($guide_method_storage->cased_name, 0, 2) !== '__'
|
||||
&& strpos($guide_method_storage->cased_name, '__') !== 0
|
||||
&& $config->isInProjectDirs(
|
||||
$implementer_param->location->file_path
|
||||
)
|
||||
|
@ -660,7 +660,7 @@ class ProjectAnalyzer
|
||||
$this->codebase->classlikes->consolidateAnalyzedData(
|
||||
$this->codebase->methods,
|
||||
$this->progress,
|
||||
!!$this->codebase->find_unused_code
|
||||
(bool)$this->codebase->find_unused_code
|
||||
);
|
||||
}
|
||||
|
||||
@ -688,7 +688,7 @@ class ProjectAnalyzer
|
||||
&& $destination_pos === (strlen($destination) - 1)
|
||||
) {
|
||||
foreach ($this->codebase->classlike_storage_provider->getAll() as $class_storage) {
|
||||
if (substr($class_storage->name, 0, $source_pos) === substr($source, 0, -1)) {
|
||||
if (strpos($source, substr($class_storage->name, 0, $source_pos)) === 0) {
|
||||
$this->to_refactor[$class_storage->name]
|
||||
= substr($destination, 0, -1) . substr($class_storage->name, $source_pos);
|
||||
}
|
||||
@ -1334,13 +1334,11 @@ class ProjectAnalyzer
|
||||
|
||||
$file_path = $this->codebase->scanner->getClassLikeFilePath($fq_class_name_lc);
|
||||
|
||||
$file_analyzer = new FileAnalyzer(
|
||||
return new FileAnalyzer(
|
||||
$this,
|
||||
$file_path,
|
||||
$this->config->shortenFileName($file_path)
|
||||
);
|
||||
|
||||
return $file_analyzer;
|
||||
}
|
||||
|
||||
public function getMethodMutations(
|
||||
|
@ -250,7 +250,7 @@ class ForeachAnalyzer
|
||||
$foreach_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
|
||||
}
|
||||
|
||||
if ($stmt->keyVar && $stmt->keyVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->keyVar->name)) {
|
||||
if ($stmt->keyVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->keyVar->name)) {
|
||||
$key_type = $key_type ?: Type::getMixed();
|
||||
|
||||
AssignmentAnalyzer::analyze(
|
||||
|
@ -159,7 +159,7 @@ class ElseIfAnalyzer
|
||||
if (array_filter(
|
||||
$entry_clauses,
|
||||
function ($clause): bool {
|
||||
return !!$clause->possibilities;
|
||||
return (bool)$clause->possibilities;
|
||||
}
|
||||
)) {
|
||||
$omit_keys = array_reduce(
|
||||
|
@ -139,7 +139,7 @@ class IfAnalyzer
|
||||
$if_scope->reasonable_clauses = Context::filterClauses(
|
||||
$var_id,
|
||||
$if_scope->reasonable_clauses,
|
||||
isset($if_context->vars_in_scope[$var_id]) ? $if_context->vars_in_scope[$var_id] : null,
|
||||
$if_context->vars_in_scope[$var_id] ?? null,
|
||||
$statements_analyzer
|
||||
);
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ class IfElseAnalyzer
|
||||
if (array_filter(
|
||||
$context->clauses,
|
||||
function ($clause): bool {
|
||||
return !!$clause->possibilities;
|
||||
return (bool)$clause->possibilities;
|
||||
}
|
||||
)) {
|
||||
$omit_keys = array_reduce(
|
||||
@ -449,9 +449,7 @@ class IfElseAnalyzer
|
||||
$if_scope->reasonable_clauses = Context::filterClauses(
|
||||
$var_id,
|
||||
$if_scope->reasonable_clauses,
|
||||
isset($context->vars_in_scope[$var_id])
|
||||
? $context->vars_in_scope[$var_id]
|
||||
: null,
|
||||
$context->vars_in_scope[$var_id] ?? null,
|
||||
$statements_analyzer
|
||||
);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ use function array_merge;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function is_string;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
@ -82,7 +83,7 @@ class SwitchCaseAnalyzer
|
||||
|
||||
$fake_switch_condition = false;
|
||||
|
||||
if ($switch_var_id && substr($switch_var_id, 0, 15) === '$__tmp_switch__') {
|
||||
if ($switch_var_id && strpos($switch_var_id, '$__tmp_switch__') === 0) {
|
||||
$switch_condition = new VirtualVariable(
|
||||
substr($switch_var_id, 1),
|
||||
$stmt->cond->getAttributes()
|
||||
@ -402,7 +403,7 @@ class SwitchCaseAnalyzer
|
||||
$case_context->inside_loop,
|
||||
new CodeLocation(
|
||||
$statements_analyzer->getSource(),
|
||||
$case->cond ? $case->cond : $case,
|
||||
$case->cond ?? $case,
|
||||
$context->include_location
|
||||
)
|
||||
);
|
||||
|
@ -21,10 +21,7 @@ class BreakAnalyzer
|
||||
if ($loop_scope) {
|
||||
if ($context->break_types
|
||||
&& \end($context->break_types) === 'switch'
|
||||
&& (!$stmt->num
|
||||
|| !$stmt->num instanceof PhpParser\Node\Scalar\LNumber
|
||||
|| $stmt->num->value < 2
|
||||
)
|
||||
&& (!$stmt->num instanceof PhpParser\Node\Scalar\LNumber || $stmt->num->value < 2)
|
||||
) {
|
||||
$loop_scope->final_actions[] = ScopeAnalyzer::ACTION_LEAVE_SWITCH;
|
||||
} else {
|
||||
|
@ -17,10 +17,7 @@ class ContinueAnalyzer
|
||||
PhpParser\Node\Stmt\Continue_ $stmt,
|
||||
Context $context
|
||||
): void {
|
||||
$count = $stmt->num
|
||||
&& $stmt->num instanceof PhpParser\Node\Scalar\LNumber
|
||||
? $stmt->num->value
|
||||
: 1;
|
||||
$count = $stmt->num instanceof PhpParser\Node\Scalar\LNumber? $stmt->num->value : 1;
|
||||
|
||||
$loop_scope = $context->loop_scope;
|
||||
|
||||
|
@ -133,7 +133,7 @@ class AssertionFinder
|
||||
$this_class_name,
|
||||
$source,
|
||||
$codebase,
|
||||
false,
|
||||
false, //should this be $inside_negation??
|
||||
$cache,
|
||||
$inside_conditional
|
||||
);
|
||||
@ -147,7 +147,7 @@ class AssertionFinder
|
||||
$this_class_name,
|
||||
$source,
|
||||
$codebase,
|
||||
false,
|
||||
false, //should this be $inside_negation??
|
||||
$cache,
|
||||
$inside_conditional
|
||||
);
|
||||
@ -2114,7 +2114,7 @@ class AssertionFinder
|
||||
?Codebase $codebase,
|
||||
bool $inside_negation,
|
||||
int $false_position
|
||||
) {
|
||||
): array {
|
||||
$if_types = [];
|
||||
|
||||
if ($false_position === self::ASSIGNMENT_TO_RIGHT) {
|
||||
@ -2492,7 +2492,7 @@ class AssertionFinder
|
||||
$if_types[$var_name] = [['!=object']];
|
||||
} elseif ($var_type === 'resource (closed)') {
|
||||
$if_types[$var_name] = [['!closed-resource']];
|
||||
} elseif (substr($var_type, 0, 10) === 'resource (') {
|
||||
} elseif (strpos($var_type, 'resource (') === 0) {
|
||||
$if_types[$var_name] = [['!=resource']];
|
||||
} else {
|
||||
$if_types[$var_name] = [['!' . $var_type]];
|
||||
@ -2550,7 +2550,7 @@ class AssertionFinder
|
||||
$if_types[$var_name] = [['!=object']];
|
||||
} elseif ($var_type === 'resource (closed)') {
|
||||
$if_types[$var_name] = [['!closed-resource']];
|
||||
} elseif (substr($var_type, 0, 10) === 'resource (') {
|
||||
} elseif (strpos($var_type, 'resource (') === 0) {
|
||||
$if_types[$var_name] = [['!=resource']];
|
||||
} else {
|
||||
$if_types[$var_name] = [['!' . $var_type]];
|
||||
@ -2807,7 +2807,7 @@ class AssertionFinder
|
||||
bool $inside_negation,
|
||||
bool $cache,
|
||||
int $true_position
|
||||
) {
|
||||
): array {
|
||||
$if_types = [];
|
||||
|
||||
if ($true_position === self::ASSIGNMENT_TO_RIGHT) {
|
||||
@ -3173,7 +3173,7 @@ class AssertionFinder
|
||||
$if_types[$var_name] = [['=object']];
|
||||
} elseif ($var_type === 'resource (closed)') {
|
||||
$if_types[$var_name] = [['closed-resource']];
|
||||
} elseif (substr($var_type, 0, 10) === 'resource (') {
|
||||
} elseif (strpos($var_type, 'resource (') === 0) {
|
||||
$if_types[$var_name] = [['=resource']];
|
||||
} else {
|
||||
$if_types[$var_name] = [[$var_type]];
|
||||
@ -3231,7 +3231,7 @@ class AssertionFinder
|
||||
$if_types[$var_name] = [['=object']];
|
||||
} elseif ($var_type === 'resource (closed)') {
|
||||
$if_types[$var_name] = [['closed-resource']];
|
||||
} elseif (substr($var_type, 0, 10) === 'resource (') {
|
||||
} elseif (strpos($var_type, 'resource (') === 0) {
|
||||
$if_types[$var_name] = [['=resource']];
|
||||
} else {
|
||||
$if_types[$var_name] = [[$var_type]];
|
||||
@ -3418,7 +3418,7 @@ class AssertionFinder
|
||||
if ($first_var_name) {
|
||||
$first_arg = $expr->args[0]->value;
|
||||
$second_arg = $expr->args[1]->value;
|
||||
$third_arg = isset($expr->args[2]->value) ? $expr->args[2]->value : null;
|
||||
$third_arg = $expr->args[2]->value ?? null;
|
||||
|
||||
if ($third_arg instanceof PhpParser\Node\Expr\ConstFetch) {
|
||||
if (!in_array(strtolower($third_arg->name->parts[0]), ['true', 'false'])) {
|
||||
|
@ -62,7 +62,6 @@ use function is_string;
|
||||
use function reset;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -232,8 +231,7 @@ class AssignmentAnalyzer
|
||||
|
||||
if ($comment_type && $comment_type_location) {
|
||||
$temp_assign_value_type = $assign_value_type
|
||||
? $assign_value_type
|
||||
: ($assign_value ? $statements_analyzer->node_data->getType($assign_value) : null);
|
||||
?? ($assign_value ? $statements_analyzer->node_data->getType($assign_value) : null);
|
||||
|
||||
if ($codebase->find_unused_variables
|
||||
&& $temp_assign_value_type
|
||||
@ -361,7 +359,7 @@ class AssignmentAnalyzer
|
||||
if (!$assign_var instanceof PhpParser\Node\Expr\PropertyFetch
|
||||
&& !strpos($root_var_id ?? '', '->')
|
||||
&& !$comment_type
|
||||
&& substr($var_id ?? '', 0, 2) !== '$_'
|
||||
&& strpos($var_id ?? '', '$_') !== 0
|
||||
) {
|
||||
$origin_locations = [];
|
||||
|
||||
@ -1350,9 +1348,8 @@ class AssignmentAnalyzer
|
||||
|
||||
$can_be_empty = !$assign_value_atomic_type instanceof Type\Atomic\TNonEmptyList;
|
||||
} elseif ($assign_value_atomic_type instanceof Type\Atomic\TKeyedArray) {
|
||||
if ($assign_var_item->key
|
||||
&& ($assign_var_item->key instanceof PhpParser\Node\Scalar\String_
|
||||
|| $assign_var_item->key instanceof PhpParser\Node\Scalar\LNumber)
|
||||
if (($assign_var_item->key instanceof PhpParser\Node\Scalar\String_
|
||||
|| $assign_var_item->key instanceof PhpParser\Node\Scalar\LNumber)
|
||||
&& isset($assign_value_atomic_type->properties[$assign_var_item->key->value])
|
||||
) {
|
||||
$new_assign_type =
|
||||
|
@ -100,8 +100,7 @@ class BitwiseNotAnalyzer
|
||||
private static function addDataFlow(
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
PhpParser\Node\Expr $stmt,
|
||||
PhpParser\Node\Expr $value,
|
||||
string $type = 'bitwisenot'
|
||||
PhpParser\Node\Expr $value
|
||||
): void {
|
||||
$result_type = $statements_analyzer->node_data->getType($stmt);
|
||||
if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $result_type) {
|
||||
@ -109,7 +108,7 @@ class BitwiseNotAnalyzer
|
||||
|
||||
$stmt_value_type = $statements_analyzer->node_data->getType($value);
|
||||
|
||||
$new_parent_node = DataFlowNode::getForAssignment($type, $var_location);
|
||||
$new_parent_node = DataFlowNode::getForAssignment('bitwisenot', $var_location);
|
||||
$statements_analyzer->data_flow_graph->addNode($new_parent_node);
|
||||
$result_type->parent_nodes = [
|
||||
$new_parent_node->id => $new_parent_node,
|
||||
@ -117,7 +116,7 @@ class BitwiseNotAnalyzer
|
||||
|
||||
if ($stmt_value_type && $stmt_value_type->parent_nodes) {
|
||||
foreach ($stmt_value_type->parent_nodes as $parent_node) {
|
||||
$statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, $type);
|
||||
$statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, 'bitwisenot');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,12 +253,12 @@ class ArgumentAnalyzer
|
||||
$param_type = \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$param_type,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$static_classlike_storage ? $static_classlike_storage->name : null,
|
||||
$classlike_storage->name ?? null,
|
||||
$static_classlike_storage->name ?? null,
|
||||
$parent_class,
|
||||
true,
|
||||
false,
|
||||
$static_classlike_storage ? $static_classlike_storage->final : false,
|
||||
$static_classlike_storage->final ?? false,
|
||||
true
|
||||
);
|
||||
|
||||
@ -384,12 +384,12 @@ class ArgumentAnalyzer
|
||||
$param_type = \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$param_type,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$static_classlike_storage ? $static_classlike_storage->name : null,
|
||||
$classlike_storage->name ?? null,
|
||||
$static_classlike_storage->name ?? null,
|
||||
$parent_class,
|
||||
true,
|
||||
false,
|
||||
$static_classlike_storage ? $static_classlike_storage->final : false,
|
||||
$static_classlike_storage->final ?? false,
|
||||
true
|
||||
);
|
||||
}
|
||||
@ -398,8 +398,8 @@ class ArgumentAnalyzer
|
||||
? \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$function_param->signature_type,
|
||||
$classlike_storage ? $classlike_storage->name : null,
|
||||
$static_classlike_storage ? $static_classlike_storage->name : null,
|
||||
$classlike_storage->name ?? null,
|
||||
$static_classlike_storage->name ?? null,
|
||||
$parent_class
|
||||
)
|
||||
: null;
|
||||
|
@ -70,8 +70,7 @@ class ArgumentsAnalyzer
|
||||
: null;
|
||||
|
||||
// if this modifies the array type based on further args
|
||||
if ($method_id
|
||||
&& in_array($method_id, ['array_push', 'array_unshift'], true)
|
||||
if (in_array($method_id, ['array_push', 'array_unshift'], true)
|
||||
&& $function_params
|
||||
&& isset($args[0])
|
||||
&& isset($args[1])
|
||||
@ -89,7 +88,7 @@ class ArgumentsAnalyzer
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($method_id && $method_id === 'array_splice' && $function_params && count($args) > 1) {
|
||||
if ($method_id === 'array_splice' && $function_params && count($args) > 1) {
|
||||
if (ArrayFunctionArgumentsAnalyzer::handleSplice($statements_analyzer, $args, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
@ -620,7 +619,7 @@ class ArgumentsAnalyzer
|
||||
$function_params[$i],
|
||||
$i,
|
||||
$i,
|
||||
$function_storage ? $function_storage->allow_named_arg_calls : true,
|
||||
$function_storage->allow_named_arg_calls ?? true,
|
||||
new VirtualArg(
|
||||
StubsGenerator::getExpressionFromType($default_type)
|
||||
),
|
||||
@ -628,7 +627,7 @@ class ArgumentsAnalyzer
|
||||
$context,
|
||||
$class_generic_params,
|
||||
$template_result,
|
||||
$function_storage ? $function_storage->specialize_call : true,
|
||||
$function_storage->specialize_call ?? true,
|
||||
$in_call_map
|
||||
);
|
||||
}
|
||||
@ -796,13 +795,13 @@ class ArgumentsAnalyzer
|
||||
$function_param,
|
||||
$argument_offset + $i,
|
||||
$i,
|
||||
$function_storage ? $function_storage->allow_named_arg_calls : true,
|
||||
$function_storage->allow_named_arg_calls ?? true,
|
||||
$arg,
|
||||
$arg_value_type,
|
||||
$context,
|
||||
$class_generic_params,
|
||||
$template_result,
|
||||
$function_storage ? $function_storage->specialize_call : true,
|
||||
$function_storage->specialize_call ?? true,
|
||||
$in_call_map
|
||||
) === false) {
|
||||
return false;
|
||||
@ -1364,12 +1363,12 @@ class ArgumentsAnalyzer
|
||||
$fleshed_out_param_type = \Psalm\Internal\Type\TypeExpander::expandUnion(
|
||||
$codebase,
|
||||
$function_param->type,
|
||||
$class_storage ? $class_storage->name : null,
|
||||
$calling_class_storage ? $calling_class_storage->name : null,
|
||||
$class_storage->name ?? null,
|
||||
$calling_class_storage->name ?? null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
$calling_class_storage ? $calling_class_storage->final : false
|
||||
$calling_class_storage->final ?? false
|
||||
);
|
||||
|
||||
TemplateStandinTypeReplacer::replace(
|
||||
|
@ -88,7 +88,7 @@ class ArrayFunctionArgumentsAnalyzer
|
||||
$array_arg_types[] = $array_arg_type;
|
||||
}
|
||||
|
||||
$closure_arg = isset($args[$closure_index]) ? $args[$closure_index] : null;
|
||||
$closure_arg = $args[$closure_index] ?? null;
|
||||
|
||||
$closure_arg_type = null;
|
||||
|
||||
|
@ -352,7 +352,7 @@ class FunctionCallAnalyzer extends CallAnalyzer
|
||||
PhpParser\Node\Name $function_name,
|
||||
Context $context,
|
||||
CodeLocation $code_location
|
||||
) {
|
||||
): FunctionCallInfo {
|
||||
$function_call_info = new FunctionCallInfo();
|
||||
|
||||
$codebase = $statements_analyzer->getCodebase();
|
||||
|
@ -12,12 +12,12 @@ class FunctionCallInfo
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
public $function_id = null;
|
||||
public $function_id;
|
||||
|
||||
/**
|
||||
* @var ?bool
|
||||
*/
|
||||
public $function_exists = null;
|
||||
public $function_exists;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
@ -42,17 +42,17 @@ class FunctionCallInfo
|
||||
/**
|
||||
* @var ?array<int, \Psalm\Storage\FunctionLikeParameter>
|
||||
*/
|
||||
public $function_params = null;
|
||||
public $function_params;
|
||||
|
||||
/**
|
||||
* @var ?\Psalm\Storage\FunctionLikeStorage
|
||||
*/
|
||||
public $function_storage = null;
|
||||
public $function_storage;
|
||||
|
||||
/**
|
||||
* @var ?PhpParser\Node\Name
|
||||
*/
|
||||
public $new_function_name = null;
|
||||
public $new_function_name;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
|
@ -222,7 +222,7 @@ class FunctionCallReturnTypeFetcher
|
||||
$fake_call_factory = new BuilderFactory();
|
||||
|
||||
if (strpos($proxy_call['fqn'], '::') !== false) {
|
||||
list($fqcn, $method) = explode('::', $proxy_call['fqn']);
|
||||
[$fqcn, $method] = explode('::', $proxy_call['fqn']);
|
||||
$fake_call = $fake_call_factory->staticCall($fqcn, $method, $fake_call_arguments);
|
||||
} else {
|
||||
$fake_call = $fake_call_factory->funcCall($proxy_call['fqn'], $fake_call_arguments);
|
||||
|
@ -660,7 +660,7 @@ class AtomicMethodCallAnalyzer extends CallAnalyzer
|
||||
PhpParser\Node\Expr\MethodCall $stmt,
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
string $fq_class_name
|
||||
) {
|
||||
): array {
|
||||
$naive_method_exists = false;
|
||||
|
||||
if ($class_storage->templatedMixins
|
||||
@ -749,7 +749,7 @@ class AtomicMethodCallAnalyzer extends CallAnalyzer
|
||||
StatementsAnalyzer $statements_analyzer,
|
||||
string $fq_class_name,
|
||||
?string $lhs_var_id
|
||||
) {
|
||||
): array {
|
||||
$naive_method_exists = false;
|
||||
|
||||
foreach ($class_storage->namedMixins as $mixin) {
|
||||
|
@ -103,9 +103,7 @@ class ExistingAtomicMethodCallAnalyzer extends CallAnalyzer
|
||||
$context
|
||||
);
|
||||
|
||||
$function_return = $statements_analyzer->node_data->getType($fake_function_call) ?: Type::getMixed();
|
||||
|
||||
return $function_return;
|
||||
return $statements_analyzer->node_data->getType($fake_function_call) ?: Type::getMixed();
|
||||
}
|
||||
|
||||
$source = $statements_analyzer->getSource();
|
||||
|
@ -127,10 +127,7 @@ class MethodVisibilityAnalyzer
|
||||
// Oldest ancestor is at end of array
|
||||
$oldest_ancestor_declaring_method_id = array_pop($overridden_method_ids);
|
||||
}
|
||||
$oldest_ancestor_declaring_method_class = null;
|
||||
if ($oldest_ancestor_declaring_method_id) {
|
||||
$oldest_ancestor_declaring_method_class = $oldest_ancestor_declaring_method_id->fq_class_name;
|
||||
}
|
||||
$oldest_ancestor_declaring_method_class = $oldest_ancestor_declaring_method_id->fq_class_name ?? null;
|
||||
|
||||
switch ($visibility) {
|
||||
case ClassLikeAnalyzer::VISIBILITY_PUBLIC:
|
||||
|
@ -60,10 +60,10 @@ class NamedFunctionCallHandler
|
||||
return;
|
||||
}
|
||||
|
||||
$first_arg = isset($stmt->args[0]) ? $stmt->args[0] : null;
|
||||
$first_arg = $stmt->args[0] ?? null;
|
||||
|
||||
if ($function_id === 'method_exists') {
|
||||
$second_arg = isset($stmt->args[1]) ? $stmt->args[1] : null;
|
||||
$second_arg = $stmt->args[1] ?? null;
|
||||
|
||||
if ($first_arg
|
||||
&& $first_arg->value instanceof PhpParser\Node\Expr\Variable
|
||||
@ -223,9 +223,7 @@ class NamedFunctionCallHandler
|
||||
if ($function_id === 'func_get_args') {
|
||||
$source = $statements_analyzer->getSource();
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $source instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
|
||||
) {
|
||||
if ($source instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer) {
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph) {
|
||||
foreach ($source->param_nodes as $param_node) {
|
||||
$statements_analyzer->data_flow_graph->addPath(
|
||||
@ -332,17 +330,13 @@ class NamedFunctionCallHandler
|
||||
) {
|
||||
$stmt_assertions = $statements_analyzer->node_data->getAssertions($stmt);
|
||||
|
||||
if ($stmt_assertions !== null) {
|
||||
$anded_assertions = $stmt_assertions;
|
||||
} else {
|
||||
$anded_assertions = AssertionFinder::processFunctionCall(
|
||||
$stmt,
|
||||
$context->self,
|
||||
$statements_analyzer,
|
||||
$codebase,
|
||||
$context->inside_negation
|
||||
);
|
||||
}
|
||||
$anded_assertions = $stmt_assertions ?? AssertionFinder::processFunctionCall(
|
||||
$stmt,
|
||||
$context->self,
|
||||
$statements_analyzer,
|
||||
$codebase,
|
||||
$context->inside_negation
|
||||
);
|
||||
|
||||
$changed_vars = [];
|
||||
|
||||
@ -442,7 +436,7 @@ class NamedFunctionCallHandler
|
||||
string $function_id,
|
||||
Context $context
|
||||
) : void {
|
||||
$first_arg = isset($stmt->args[0]) ? $stmt->args[0] : null;
|
||||
$first_arg = $stmt->args[0] ?? null;
|
||||
|
||||
if ($first_arg) {
|
||||
$var = $first_arg->value;
|
||||
|
@ -191,17 +191,12 @@ class CallAnalyzer
|
||||
|| $is_final)
|
||||
) {
|
||||
$local_vars_in_scope = [];
|
||||
$local_vars_possibly_in_scope = [];
|
||||
|
||||
foreach ($context->vars_in_scope as $var_id => $type) {
|
||||
if (strpos($var_id, '$this->') === 0) {
|
||||
if ($type->initialized) {
|
||||
$local_vars_in_scope[$var_id] = $context->vars_in_scope[$var_id];
|
||||
|
||||
if (isset($context->vars_possibly_in_scope[$var_id])) {
|
||||
$local_vars_possibly_in_scope[$var_id] = $context->vars_possibly_in_scope[$var_id];
|
||||
}
|
||||
|
||||
unset($context->vars_in_scope[$var_id]);
|
||||
unset($context->vars_possibly_in_scope[$var_id]);
|
||||
}
|
||||
@ -320,7 +315,7 @@ class CallAnalyzer
|
||||
$args,
|
||||
$method_params,
|
||||
(string) $method_id,
|
||||
$method_storage ? $method_storage->allow_named_arg_calls : true,
|
||||
$method_storage->allow_named_arg_calls ?? true,
|
||||
$context,
|
||||
$class_template_result
|
||||
) === false) {
|
||||
@ -419,11 +414,11 @@ class CallAnalyzer
|
||||
$codebase,
|
||||
$type,
|
||||
$appearing_class_name,
|
||||
$calling_class_storage ? $calling_class_storage->name : null,
|
||||
$calling_class_storage->name ?? null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
$calling_class_storage ? $calling_class_storage->final : false
|
||||
$calling_class_storage->final ?? false
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1032,7 +1027,7 @@ class CallAnalyzer
|
||||
$bounds_with_equality = array_filter(
|
||||
$lower_bounds,
|
||||
function ($lower_bound) {
|
||||
return !!$lower_bound->equality_bound_classlike;
|
||||
return (bool)$lower_bound->equality_bound_classlike;
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -66,8 +66,7 @@ class CastAnalyzer
|
||||
new Type\Atomic\TLiteralInt(1),
|
||||
]);
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
) {
|
||||
$type->parent_nodes = $maybe_type->parent_nodes;
|
||||
}
|
||||
@ -79,10 +78,9 @@ class CastAnalyzer
|
||||
if ($as_int) {
|
||||
$type = $valid_int_type ?? Type::getInt();
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
) {
|
||||
$type->parent_nodes = $maybe_type ? $maybe_type->parent_nodes : [];
|
||||
$type->parent_nodes = $maybe_type->parent_nodes ?? [];
|
||||
}
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, $type);
|
||||
@ -106,10 +104,9 @@ class CastAnalyzer
|
||||
|
||||
$type = Type::getFloat();
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
) {
|
||||
$type->parent_nodes = $maybe_type ? $maybe_type->parent_nodes : [];
|
||||
$type->parent_nodes = $maybe_type->parent_nodes ?? [];
|
||||
}
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, $type);
|
||||
@ -132,10 +129,9 @@ class CastAnalyzer
|
||||
|
||||
$type = Type::getBool();
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
) {
|
||||
$type->parent_nodes = $maybe_type ? $maybe_type->parent_nodes : [];
|
||||
$type->parent_nodes = $maybe_type->parent_nodes ?? [];
|
||||
}
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, $type);
|
||||
@ -183,10 +179,9 @@ class CastAnalyzer
|
||||
|
||||
$maybe_type = $statements_analyzer->node_data->getType($stmt->expr);
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
) {
|
||||
$type->parent_nodes = $maybe_type ? $maybe_type->parent_nodes : [];
|
||||
$type->parent_nodes = $maybe_type->parent_nodes ?? [];
|
||||
}
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, $type);
|
||||
@ -237,10 +232,9 @@ class CastAnalyzer
|
||||
$type = Type::getArray();
|
||||
}
|
||||
|
||||
if ($statements_analyzer->data_flow_graph
|
||||
&& $statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
if ($statements_analyzer->data_flow_graph instanceof \Psalm\Internal\Codebase\VariableUseGraph
|
||||
) {
|
||||
$type->parent_nodes = $stmt_expr_type ? $stmt_expr_type->parent_nodes : [];
|
||||
$type->parent_nodes = $stmt_expr_type->parent_nodes ?? [];
|
||||
}
|
||||
|
||||
$statements_analyzer->node_data->setType($stmt, $type);
|
||||
|
@ -1833,8 +1833,7 @@ class ArrayFetchAnalyzer
|
||||
[
|
||||
new VirtualArg(
|
||||
$stmt->dim
|
||||
? $stmt->dim
|
||||
: new VirtualConstFetch(
|
||||
?? new VirtualConstFetch(
|
||||
new VirtualName('null'),
|
||||
$stmt->var->getAttributes()
|
||||
)
|
||||
@ -1957,7 +1956,7 @@ class ArrayFetchAnalyzer
|
||||
if ($type instanceof TSingleLetter) {
|
||||
$valid_offset_type = Type::getInt(false, 0);
|
||||
} elseif ($type instanceof TLiteralString) {
|
||||
if (!strlen($type->value)) {
|
||||
if ($type->value === '') {
|
||||
$valid_offset_type = Type::getEmpty();
|
||||
} elseif (strlen($type->value) < 10) {
|
||||
$valid_offsets = [];
|
||||
|
@ -1112,8 +1112,6 @@ class AtomicPropertyFetchAnalyzer
|
||||
$has_magic_getter,
|
||||
$var_id
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private static function getClassPropertyType(
|
||||
|
@ -84,7 +84,7 @@ class IncludeAnalyzer
|
||||
|
||||
// attempts to resolve using get_include_path dirs
|
||||
$include_path = self::resolveIncludePath($path_to_file, dirname($statements_analyzer->getFilePath()));
|
||||
$path_to_file = $include_path ? $include_path : $path_to_file;
|
||||
$path_to_file = $include_path ?: $path_to_file;
|
||||
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
$is_path_relative = $path_to_file[0] !== DIRECTORY_SEPARATOR;
|
||||
|
@ -282,9 +282,7 @@ class SimpleTypeInferer
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return null;
|
||||
} catch (\Psalm\Exception\CircularReferenceException $e) {
|
||||
} catch (\InvalidArgumentException | \Psalm\Exception\CircularReferenceException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -633,7 +633,7 @@ class ReturnAnalyzer
|
||||
$param->type = self::inferInnerClosureTypeFromParent(
|
||||
$statements_analyzer->getCodebase(),
|
||||
$param->type,
|
||||
$parent_param ? $parent_param->type : null
|
||||
$parent_param->type ?? null
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ class UnusedAssignmentRemover
|
||||
$iter = 1;
|
||||
|
||||
// Check if second token is just whitespace
|
||||
if (is_array($token_list[$iter]) && strlen(trim($token_list[$iter][1])) === 0) {
|
||||
if (is_array($token_list[$iter]) && trim($token_list[$iter][1]) === '') {
|
||||
$offset_count += strlen($token_list[1][1]);
|
||||
$iter++;
|
||||
}
|
||||
@ -146,7 +146,7 @@ class UnusedAssignmentRemover
|
||||
$iter++;
|
||||
|
||||
// Remove any whitespace following assignment operator token (e.g "=", "+=")
|
||||
if (is_array($token_list[$iter]) && strlen(trim($token_list[$iter][1])) === 0) {
|
||||
if (is_array($token_list[$iter]) && trim($token_list[$iter][1]) === '') {
|
||||
$offset_count += strlen($token_list[$iter][1]);
|
||||
$iter++;
|
||||
}
|
||||
@ -156,7 +156,7 @@ class UnusedAssignmentRemover
|
||||
$offset_count += 1;
|
||||
$iter++;
|
||||
// Handle any whitespace after "&"
|
||||
if (is_array($token_list[$iter]) && strlen(trim($token_list[$iter][1])) === 0) {
|
||||
if (is_array($token_list[$iter]) && trim($token_list[$iter][1]) === '') {
|
||||
$offset_count += strlen($token_list[$iter][1]);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ use function get_class;
|
||||
use function preg_split;
|
||||
use function round;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strrpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
@ -117,12 +118,12 @@ class StatementsAnalyzer extends SourceAnalyzer
|
||||
/**
|
||||
* @var ParsedDocblock|null
|
||||
*/
|
||||
private $parsed_docblock = null;
|
||||
private $parsed_docblock;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
private $fake_this_class = null;
|
||||
private $fake_this_class;
|
||||
|
||||
/** @var \Psalm\Internal\Provider\NodeDataProvider */
|
||||
public $node_data;
|
||||
@ -557,7 +558,7 @@ class StatementsAnalyzer extends SourceAnalyzer
|
||||
$class_analyzer = new ClassAnalyzer(
|
||||
$stmt,
|
||||
$statements_analyzer->source,
|
||||
$stmt->name ? $stmt->name->name : null
|
||||
$stmt->name->name ?? null
|
||||
);
|
||||
|
||||
$class_analyzer->analyze(null, $global_context);
|
||||
@ -755,7 +756,7 @@ class StatementsAnalyzer extends SourceAnalyzer
|
||||
}
|
||||
|
||||
foreach ($this->unused_var_locations as [$var_id, $original_location]) {
|
||||
if (substr($var_id, 0, 2) === '$_') {
|
||||
if (strpos($var_id, '$_') === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -911,12 +912,12 @@ class StatementsAnalyzer extends SourceAnalyzer
|
||||
*/
|
||||
public function getFirstAppearance(string $var_id): ?CodeLocation
|
||||
{
|
||||
return isset($this->all_vars[$var_id]) ? $this->all_vars[$var_id] : null;
|
||||
return $this->all_vars[$var_id] ?? null;
|
||||
}
|
||||
|
||||
public function getBranchPoint(string $var_id): ?int
|
||||
{
|
||||
return isset($this->var_branch_points[$var_id]) ? $this->var_branch_points[$var_id] : null;
|
||||
return $this->var_branch_points[$var_id] ?? null;
|
||||
}
|
||||
|
||||
public function addVariableInitialization(string $var_id, int $branch_point): void
|
||||
|
@ -27,6 +27,7 @@ use function is_string;
|
||||
use function preg_replace;
|
||||
use function realpath;
|
||||
use function setlocale;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
@ -85,7 +86,7 @@ final class LanguageServer
|
||||
* @param string $arg
|
||||
*/
|
||||
function ($arg) use ($valid_long_options): void {
|
||||
if (substr($arg, 0, 2) === '--' && $arg !== '--') {
|
||||
if (strpos($arg, '--') === 0 && $arg !== '--') {
|
||||
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
|
||||
|
||||
if (!in_array($arg_name, $valid_long_options, true)
|
||||
@ -309,6 +310,6 @@ HELP;
|
||||
$project_analyzer->language_server_verbose = true;
|
||||
}
|
||||
|
||||
$project_analyzer->server($options['tcp'] ?? null, isset($options['tcp-server']) ? true : false);
|
||||
$project_analyzer->server($options['tcp'] ?? null, isset($options['tcp-server']));
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ final class Psalm
|
||||
}
|
||||
}
|
||||
|
||||
$paths_to_check = CliUtils::getPathsToCheck(isset($options['f']) ? $options['f'] : null);
|
||||
$paths_to_check = CliUtils::getPathsToCheck($options['f'] ?? null);
|
||||
|
||||
if ($config->resolve_from_config_file) {
|
||||
$current_dir = $config->base_dir;
|
||||
@ -420,7 +420,7 @@ final class Psalm
|
||||
* @param string $arg
|
||||
*/
|
||||
function ($arg): void {
|
||||
if (substr($arg, 0, 2) === '--' && $arg !== '--') {
|
||||
if (strpos($arg, '--') === 0 && $arg !== '--') {
|
||||
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
|
||||
|
||||
if (!in_array($arg_name, self::LONG_OPTIONS)
|
||||
@ -434,7 +434,7 @@ final class Psalm
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
} elseif (substr($arg, 0, 1) === '-' && $arg !== '-' && $arg !== '--') {
|
||||
} elseif (strpos($arg, '-') === 0 && $arg !== '-' && $arg !== '--') {
|
||||
$arg_name = preg_replace('/=.*$/', '', substr($arg, 1));
|
||||
|
||||
if (!in_array($arg_name, self::SHORT_OPTIONS)
|
||||
|
@ -201,7 +201,7 @@ HELP;
|
||||
// If Xdebug is enabled, restart without it
|
||||
(new \Composer\XdebugHandler\XdebugHandler('PSALTER'))->check();
|
||||
|
||||
$paths_to_check = CliUtils::getPathsToCheck(isset($options['f']) ? $options['f'] : null);
|
||||
$paths_to_check = CliUtils::getPathsToCheck($options['f'] ?? null);
|
||||
|
||||
$path_to_config = CliUtils::getPathToConfig($options);
|
||||
|
||||
@ -434,7 +434,7 @@ HELP;
|
||||
* @param string $arg
|
||||
*/
|
||||
function ($arg): void {
|
||||
if (substr($arg, 0, 2) === '--' && $arg !== '--') {
|
||||
if (strpos($arg, '--') === 0 && $arg !== '--') {
|
||||
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
|
||||
|
||||
if ($arg_name === 'alter') {
|
||||
|
@ -75,7 +75,7 @@ final class Refactor
|
||||
* @param string $arg
|
||||
*/
|
||||
function ($arg) use ($valid_long_options): void {
|
||||
if (substr($arg, 0, 2) === '--' && $arg !== '--') {
|
||||
if (strpos($arg, '--') === 0 && $arg !== '--') {
|
||||
$arg_name = preg_replace('/=.*$/', '', substr($arg, 2));
|
||||
|
||||
if ($arg_name === 'refactor') {
|
||||
|
@ -231,7 +231,7 @@ final class CliUtils
|
||||
if ($f_paths) {
|
||||
$input_paths = is_array($f_paths) ? $f_paths : [$f_paths];
|
||||
} else {
|
||||
$input_paths = $argv ? $argv : null;
|
||||
$input_paths = $argv ?: null;
|
||||
}
|
||||
|
||||
if ($input_paths) {
|
||||
@ -264,7 +264,7 @@ final class CliUtils
|
||||
continue;
|
||||
}
|
||||
|
||||
if (substr($input_path, 0, 2) === '--' && strlen($input_path) > 2) {
|
||||
if (strpos($input_path, '--') === 0 && strlen($input_path) > 2) {
|
||||
if (substr($input_path, 2) === 'config') {
|
||||
++$i;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ class Analyzer
|
||||
*
|
||||
* @var array<string>|null
|
||||
*/
|
||||
private $files_to_update = null;
|
||||
private $files_to_update;
|
||||
|
||||
/**
|
||||
* @var array<string, array<string, int>>
|
||||
@ -316,7 +316,7 @@ class Analyzer
|
||||
|
||||
$project_analyzer->prepareMigration();
|
||||
|
||||
$files_to_update = $this->files_to_update !== null ? $this->files_to_update : $this->files_to_analyze;
|
||||
$files_to_update = $this->files_to_update ?? $this->files_to_analyze;
|
||||
|
||||
foreach ($files_to_update as $file_path) {
|
||||
$this->updateFile($file_path, $project_analyzer->dry_run);
|
||||
@ -345,7 +345,7 @@ class Analyzer
|
||||
|
||||
$this->progress->debug('Analyzing ' . $file_analyzer->getFilePath() . "\n");
|
||||
|
||||
$file_analyzer->analyze(null);
|
||||
$file_analyzer->analyze();
|
||||
$file_analyzer->context = null;
|
||||
$file_analyzer->clearSourceBeforeDestruction();
|
||||
unset($file_analyzer);
|
||||
|
@ -134,12 +134,12 @@ class ConstantTypeResolver
|
||||
|| $cond instanceof Type\Atomic\TLiteralString
|
||||
) {
|
||||
if ($cond->value) {
|
||||
return $if ? $if : $cond;
|
||||
return $if ?? $cond;
|
||||
}
|
||||
} elseif ($cond instanceof Type\Atomic\TFalse || $cond instanceof Type\Atomic\TNull) {
|
||||
return $else;
|
||||
} elseif ($cond instanceof Type\Atomic\TTrue) {
|
||||
return $if ? $if : $cond;
|
||||
return $if ?? $cond;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ use function array_merge;
|
||||
use function array_reverse;
|
||||
use function array_sum;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function substr;
|
||||
|
||||
abstract class DataFlowGraph
|
||||
@ -65,7 +66,7 @@ abstract class DataFlowGraph
|
||||
|
||||
// arraykey-fetch requires a matching arraykey-assignment at the same level
|
||||
// otherwise the tainting is not valid
|
||||
if (substr($path_type, 0, $el + 7) === $expression_type . '-fetch-' || $path_type === 'arraykey-fetch') {
|
||||
if (strpos($path_type, $expression_type . '-fetch-') === 0 || $path_type === 'arraykey-fetch') {
|
||||
$fetch_nesting = 0;
|
||||
|
||||
$previous_path_types = array_reverse($previous_path_types);
|
||||
@ -79,11 +80,11 @@ abstract class DataFlowGraph
|
||||
$fetch_nesting--;
|
||||
}
|
||||
|
||||
if (substr($previous_path_type, 0, $el + 6) === $expression_type . '-fetch') {
|
||||
if (strpos($previous_path_type, $expression_type . '-fetch') === 0) {
|
||||
$fetch_nesting++;
|
||||
}
|
||||
|
||||
if (substr($previous_path_type, 0, $el + 12) === $expression_type . '-assignment-') {
|
||||
if (strpos($previous_path_type, $expression_type . '-assignment-') === 0) {
|
||||
if ($fetch_nesting > 0) {
|
||||
$fetch_nesting--;
|
||||
continue;
|
||||
|
@ -14,6 +14,7 @@ use function assert;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_exists;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
use function version_compare;
|
||||
@ -32,16 +33,16 @@ class InternalCallMapHandler
|
||||
/**
|
||||
* @var ?int
|
||||
*/
|
||||
private static $loaded_php_major_version = null;
|
||||
private static $loaded_php_major_version;
|
||||
/**
|
||||
* @var ?int
|
||||
*/
|
||||
private static $loaded_php_minor_version = null;
|
||||
private static $loaded_php_minor_version;
|
||||
|
||||
/**
|
||||
* @var array<lowercase-string, array<int|string,string>>|null
|
||||
*/
|
||||
private static $call_map = null;
|
||||
private static $call_map;
|
||||
|
||||
/**
|
||||
* @var array<list<TCallable>>|null
|
||||
@ -274,7 +275,7 @@ class InternalCallMapHandler
|
||||
$optional = true;
|
||||
}
|
||||
|
||||
if (substr($arg_name, 0, 3) === '...') {
|
||||
if (strpos($arg_name, '...') === 0) {
|
||||
$arg_name = substr($arg_name, 3);
|
||||
$variadic = true;
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ class Methods
|
||||
if (InternalCallMapHandler::inCallMap((string) $callmap_id)) {
|
||||
$class_storage = $this->classlike_storage_provider->get($callmap_id->fq_class_name);
|
||||
|
||||
$declaring_method_name = $declaring_method_id ? $declaring_method_id->method_name : $method_name;
|
||||
$declaring_method_name = $declaring_method_id->method_name ?? $method_name;
|
||||
|
||||
if (!$class_storage->stubbed || empty($class_storage->methods[$declaring_method_name]->stubbed)) {
|
||||
$function_callables = InternalCallMapHandler::getCallablesFromCallMap((string) $callmap_id);
|
||||
@ -1060,11 +1060,7 @@ class Methods
|
||||
|
||||
$method_name = $method_id->method_name;
|
||||
|
||||
if (isset($class_storage->appearing_method_ids[$method_name])) {
|
||||
return $class_storage->appearing_method_ids[$method_name];
|
||||
}
|
||||
|
||||
return null;
|
||||
return $class_storage->appearing_method_ids[$method_name] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1075,11 +1071,7 @@ class Methods
|
||||
$class_storage = $this->classlike_storage_provider->get($method_id->fq_class_name);
|
||||
$method_name = $method_id->method_name;
|
||||
|
||||
if (isset($class_storage->overridden_method_ids[$method_name])) {
|
||||
return $class_storage->overridden_method_ids[$method_name];
|
||||
}
|
||||
|
||||
return [];
|
||||
return $class_storage->overridden_method_ids[$method_name] ?? [];
|
||||
}
|
||||
|
||||
public function getCasedMethodId(MethodIdentifier $original_method_id): string
|
||||
|
@ -35,7 +35,7 @@ final class Composer
|
||||
*/
|
||||
public static function getLockFilePath(string $root): string
|
||||
{
|
||||
$composer_json_path = static::getJsonFilePath($root);
|
||||
$composer_json_path = self::getJsonFilePath($root);
|
||||
return "json" === pathinfo($composer_json_path, PATHINFO_EXTENSION)
|
||||
? substr($composer_json_path, 0, -4).'lock'
|
||||
: $composer_json_path . '.lock';
|
||||
|
@ -24,7 +24,7 @@ final class SystemCommandExecutor
|
||||
{
|
||||
if (!\function_exists('exec')) {
|
||||
throw new \RuntimeException(sprintf('exec does not exist, failed to execute command: %s', $command));
|
||||
};
|
||||
}
|
||||
|
||||
exec($command, $result, $returnValue);
|
||||
|
||||
|
@ -169,11 +169,7 @@ class FileManipulationBuffer
|
||||
*/
|
||||
public static function getManipulationsForFile(string $file_path): array
|
||||
{
|
||||
if (!isset(self::$file_manipulations[$file_path])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return self::$file_manipulations[$file_path];
|
||||
return self::$file_manipulations[$file_path] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,6 @@ use function get_class;
|
||||
use function gettype;
|
||||
use function in_array;
|
||||
use function ini_get;
|
||||
use function intval;
|
||||
use function pcntl_fork;
|
||||
use function pcntl_waitpid;
|
||||
use function pcntl_wexitstatus;
|
||||
@ -307,7 +306,7 @@ class Pool
|
||||
// resource id.
|
||||
$streams = [];
|
||||
foreach ($this->read_streams as $stream) {
|
||||
$streams[intval($stream)] = $stream;
|
||||
$streams[(int)$stream] = $stream;
|
||||
}
|
||||
|
||||
// Create an array for the content received on each stream,
|
||||
@ -340,12 +339,12 @@ class Pool
|
||||
foreach ($needs_read as $file) {
|
||||
$buffer = fread($file, 1024);
|
||||
if ($buffer !== false) {
|
||||
$content[intval($file)] .= $buffer;
|
||||
$content[(int)$file] .= $buffer;
|
||||
}
|
||||
|
||||
if (strpos($buffer, "\n") !== false) {
|
||||
$serialized_messages = explode("\n", $content[intval($file)]);
|
||||
$content[intval($file)] = array_pop($serialized_messages);
|
||||
$serialized_messages = explode("\n", $content[(int)$file]);
|
||||
$content[(int)$file] = array_pop($serialized_messages);
|
||||
|
||||
foreach ($serialized_messages as $serialized_message) {
|
||||
$message = unserialize(base64_decode($serialized_message, true));
|
||||
@ -375,13 +374,13 @@ class Pool
|
||||
|
||||
// If the stream has closed, stop trying to select on it.
|
||||
if (feof($file)) {
|
||||
if ($content[intval($file)] !== '') {
|
||||
if ($content[(int)$file] !== '') {
|
||||
error_log('Child did not send full message before closing the connection');
|
||||
$this->did_have_error = true;
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
unset($streams[intval($file)]);
|
||||
unset($streams[(int)$file]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
|
||||
|
||||
$this->verboseLog("Initializing: Registering stub files...");
|
||||
$this->clientStatus('initializing', 'registering stub files');
|
||||
$codebase->config->visitStubFiles($codebase, null);
|
||||
$codebase->config->visitStubFiles($codebase);
|
||||
|
||||
if ($this->textDocument === null) {
|
||||
$this->textDocument = new TextDocument(
|
||||
|
@ -37,7 +37,7 @@ class ProtocolStreamReader implements ProtocolReader
|
||||
/** @var string[] */
|
||||
private $headers = [];
|
||||
/** @var ?int */
|
||||
private $content_length = null;
|
||||
private $content_length;
|
||||
/** @var bool */
|
||||
private $did_emit_close = false;
|
||||
|
||||
|
@ -26,24 +26,17 @@ class AttributeResolver
|
||||
) : AttributeStorage {
|
||||
if ($stmt->name instanceof PhpParser\Node\Name\FullyQualified) {
|
||||
$fq_type_string = (string)$stmt->name;
|
||||
|
||||
$codebase->scanner->queueClassLikeForScanning($fq_type_string);
|
||||
$file_storage->referenced_classlikes[strtolower($fq_type_string)] = $fq_type_string;
|
||||
} else {
|
||||
$fq_type_string = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->name, $aliases);
|
||||
|
||||
$codebase->scanner->queueClassLikeForScanning($fq_type_string);
|
||||
$file_storage->referenced_classlikes[strtolower($fq_type_string)] = $fq_type_string;
|
||||
}
|
||||
|
||||
$codebase->scanner->queueClassLikeForScanning($fq_type_string);
|
||||
$file_storage->referenced_classlikes[strtolower($fq_type_string)] = $fq_type_string;
|
||||
|
||||
$args = [];
|
||||
|
||||
foreach ($stmt->args as $arg_node) {
|
||||
$key = null;
|
||||
|
||||
if ($arg_node->name) {
|
||||
$key = $arg_node->name->name;
|
||||
}
|
||||
$key = $arg_node->name->name ?? null;
|
||||
|
||||
$const_type = SimpleTypeInferer::infer(
|
||||
$codebase,
|
||||
|
@ -489,7 +489,7 @@ class ClassLikeDocblockParser
|
||||
array $specials,
|
||||
string $property_tag
|
||||
) : void {
|
||||
$magic_property_comments = isset($specials[$property_tag]) ? $specials[$property_tag] : [];
|
||||
$magic_property_comments = $specials[$property_tag] ?? [];
|
||||
|
||||
foreach ($magic_property_comments as $offset => $property) {
|
||||
$line_parts = CommentAnalyzer::splitDocLine($property);
|
||||
|
@ -366,12 +366,7 @@ class ClassLikeNodeScanner
|
||||
if ($type_aliases) {
|
||||
$this->classlike_type_aliases = $type_aliases;
|
||||
}
|
||||
} catch (DocblockParseException $e) {
|
||||
$storage->docblock_issues[] = new InvalidDocblock(
|
||||
$e->getMessage(),
|
||||
new CodeLocation($this->file_scanner, $node, null, true)
|
||||
);
|
||||
} catch (TypeParseTreeException $e) {
|
||||
} catch (DocblockParseException | TypeParseTreeException $e) {
|
||||
$storage->docblock_issues[] = new InvalidDocblock(
|
||||
$e->getMessage(),
|
||||
new CodeLocation($this->file_scanner, $node, null, true)
|
||||
@ -1390,7 +1385,7 @@ class ClassLikeNodeScanner
|
||||
);
|
||||
}
|
||||
|
||||
$doc_var_group_type = $var_comment ? $var_comment->type : null;
|
||||
$doc_var_group_type = $var_comment->type ?? null;
|
||||
|
||||
if ($doc_var_group_type) {
|
||||
$doc_var_group_type->queueClassLikesForScanning($this->codebase, $this->file_storage);
|
||||
@ -1408,7 +1403,7 @@ class ClassLikeNodeScanner
|
||||
$property_storage->type_location = $signature_type_location;
|
||||
$property_storage->location = new CodeLocation($this->file_scanner, $property->name);
|
||||
$property_storage->stmt_location = new CodeLocation($this->file_scanner, $stmt);
|
||||
$property_storage->has_default = $property->default ? true : false;
|
||||
$property_storage->has_default = (bool)$property->default;
|
||||
$property_storage->deprecated = $var_comment ? $var_comment->deprecated : false;
|
||||
$property_storage->suppressed_issues = $var_comment ? $var_comment->suppressed_issues : [];
|
||||
$property_storage->internal = $var_comment ? $var_comment->psalm_internal ?? '' : '';
|
||||
|
@ -281,7 +281,7 @@ class ExpressionScanner
|
||||
|
||||
// attempts to resolve using get_include_path dirs
|
||||
$include_path = IncludeAnalyzer::resolveIncludePath($path_to_file, dirname($file_storage->file_path));
|
||||
$path_to_file = $include_path ? $include_path : $path_to_file;
|
||||
$path_to_file = $include_path ?: $path_to_file;
|
||||
|
||||
if (DIRECTORY_SEPARATOR === '/') {
|
||||
$is_path_relative = $path_to_file[0] !== DIRECTORY_SEPARATOR;
|
||||
|
@ -20,6 +20,7 @@ use function preg_replace;
|
||||
use function preg_split;
|
||||
use function reset;
|
||||
use function str_replace;
|
||||
use function stripos;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
@ -199,7 +200,7 @@ class FunctionLikeDocblockParser
|
||||
if (count($param_parts) === 2) {
|
||||
$taint_type = $param_parts[1];
|
||||
|
||||
if (substr($taint_type, 0, 5) === 'exec_') {
|
||||
if (strpos($taint_type, 'exec_') === 0) {
|
||||
$taint_type = substr($taint_type, 5);
|
||||
|
||||
if ($taint_type === 'tainted') {
|
||||
@ -375,7 +376,7 @@ class FunctionLikeDocblockParser
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos(strtolower($parsed_docblock->description), '@inheritdoc') !== false
|
||||
if (stripos($parsed_docblock->description, '@inheritdoc') !== false
|
||||
|| isset($parsed_docblock->tags['inheritdoc'])
|
||||
|| isset($parsed_docblock->tags['inheritDoc'])
|
||||
) {
|
||||
@ -490,7 +491,7 @@ class FunctionLikeDocblockParser
|
||||
* @param list<string> $line_parts
|
||||
* @return array{string, string} $line_parts
|
||||
*/
|
||||
private static function sanitizeAssertionLineParts(array $line_parts)
|
||||
private static function sanitizeAssertionLineParts(array $line_parts): array
|
||||
{
|
||||
if (count($line_parts) < 2 || strpos($line_parts[1], '$') === false) {
|
||||
throw new IncorrectDocblockException('Misplaced variable');
|
||||
|
@ -617,7 +617,7 @@ class FunctionLikeDocblockScanner
|
||||
$param_name = $docblock_param['name'];
|
||||
$docblock_param_variadic = false;
|
||||
|
||||
if (substr($param_name, 0, 3) === '...') {
|
||||
if (strpos($param_name, '...') === 0) {
|
||||
$docblock_param_variadic = true;
|
||||
$param_name = substr($param_name, 3);
|
||||
}
|
||||
@ -987,7 +987,7 @@ class FunctionLikeDocblockScanner
|
||||
|
||||
if (isset($flow_parts[0]) && \strpos(trim($flow_parts[0]), 'proxy') === 0) {
|
||||
$proxy_call = trim(substr($flow_parts[0], strlen('proxy')));
|
||||
list($fully_qualified_name, $source_param_string) = explode('(', $proxy_call, 2);
|
||||
[$fully_qualified_name, $source_param_string] = explode('(', $proxy_call, 2);
|
||||
|
||||
if (!empty($fully_qualified_name) && !empty($source_param_string)) {
|
||||
$source_params = preg_split('/, ?/', substr($source_param_string, 0, -1)) ?: [];
|
||||
|
@ -218,7 +218,7 @@ class FunctionLikeNodeScanner
|
||||
}
|
||||
|
||||
$existing_params['$' . $param_storage->name] = $i;
|
||||
$storage->addParam($param_storage, !!$param->type);
|
||||
$storage->addParam($param_storage, (bool)$param->type);
|
||||
|
||||
if (!$param_storage->is_optional && !$param_storage->is_variadic) {
|
||||
$required_param_count = $i + 1;
|
||||
@ -292,7 +292,7 @@ class FunctionLikeNodeScanner
|
||||
$cond_id,
|
||||
$cond_id,
|
||||
$function_stmt->cond,
|
||||
$this->classlike_storage ? $this->classlike_storage->name : null,
|
||||
$this->classlike_storage->name ?? null,
|
||||
$this->file_scanner,
|
||||
null
|
||||
);
|
||||
@ -585,7 +585,7 @@ class FunctionLikeNodeScanner
|
||||
$property_storage->type_location = $param_storage->type_location;
|
||||
$property_storage->location = $param_storage->location;
|
||||
$property_storage->stmt_location = new CodeLocation($this->file_scanner, $param);
|
||||
$property_storage->has_default = $param->default ? true : false;
|
||||
$property_storage->has_default = (bool)$param->default;
|
||||
$param_storage->promoted_property = true;
|
||||
$property_storage->is_promoted = true;
|
||||
|
||||
|
@ -92,7 +92,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSour
|
||||
/**
|
||||
* @var ?int
|
||||
*/
|
||||
private $skip_if_descendants = null;
|
||||
private $skip_if_descendants;
|
||||
|
||||
/**
|
||||
* @var array<string, TypeAlias>
|
||||
@ -126,17 +126,12 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSour
|
||||
{
|
||||
foreach ($node->getComments() as $comment) {
|
||||
if ($comment instanceof PhpParser\Comment\Doc && !$node instanceof PhpParser\Node\Stmt\ClassLike) {
|
||||
$self_fqcln = $node instanceof PhpParser\Node\Stmt\ClassLike
|
||||
&& $node->name !== null
|
||||
? ($this->aliases->namespace ? $this->aliases->namespace . '\\' : '') . $node->name->name
|
||||
: null;
|
||||
|
||||
try {
|
||||
$type_aliases = Reflector\ClassLikeNodeScanner::getTypeAliasesFromComment(
|
||||
$comment,
|
||||
$this->aliases,
|
||||
$this->type_aliases,
|
||||
$self_fqcln
|
||||
null
|
||||
);
|
||||
|
||||
foreach ($type_aliases as $type_alias) {
|
||||
@ -145,12 +140,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSour
|
||||
}
|
||||
|
||||
$this->type_aliases += $type_aliases;
|
||||
} catch (DocblockParseException $e) {
|
||||
$this->file_storage->docblock_issues[] = new InvalidDocblock(
|
||||
$e->getMessage(),
|
||||
new CodeLocation($this->file_scanner, $node, null, true)
|
||||
);
|
||||
} catch (TypeParseTreeException $e) {
|
||||
} catch (DocblockParseException | TypeParseTreeException $e) {
|
||||
$this->file_storage->docblock_issues[] = new InvalidDocblock(
|
||||
$e->getMessage(),
|
||||
new CodeLocation($this->file_scanner, $node, null, true)
|
||||
@ -434,7 +424,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSour
|
||||
foreach ($node->uses as $use) {
|
||||
$use_path = implode('\\', $use->name->parts);
|
||||
|
||||
$use_alias = $use->alias ? $use->alias->name : $use->name->getLast();
|
||||
$use_alias = $use->alias->name ?? $use->name->getLast();
|
||||
|
||||
switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $node->type) {
|
||||
case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
|
||||
@ -467,7 +457,7 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSour
|
||||
|
||||
foreach ($node->uses as $use) {
|
||||
$use_path = $use_prefix . '\\' . implode('\\', $use->name->parts);
|
||||
$use_alias = $use->alias ? $use->alias->name : $use->name->getLast();
|
||||
$use_alias = $use->alias->name ?? $use->name->getLast();
|
||||
|
||||
switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $node->type) {
|
||||
case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
|
||||
|
@ -68,7 +68,7 @@ class SimpleNameResolver extends NodeVisitorAbstract
|
||||
$this->nameContext->startNamespace($node->name);
|
||||
} elseif ($node instanceof Stmt\Use_) {
|
||||
foreach ($node->uses as $use) {
|
||||
$this->addAlias($use, $node->type, null);
|
||||
$this->addAlias($use, $node->type);
|
||||
}
|
||||
} elseif ($node instanceof Stmt\GroupUse) {
|
||||
foreach ($node->uses as $use) {
|
||||
|
@ -18,10 +18,10 @@ class PluginList
|
||||
private $composer_lock;
|
||||
|
||||
/** @var ?array<string,string> [pluginClass => packageName] */
|
||||
private $all_plugins = null;
|
||||
private $all_plugins;
|
||||
|
||||
/** @var ?array<string,?string> [pluginClass => ?packageName] */
|
||||
private $enabled_plugins = null;
|
||||
private $enabled_plugins;
|
||||
|
||||
public function __construct(?ConfigFile $config_file, ComposerLock $composer_lock)
|
||||
{
|
||||
|
@ -29,11 +29,7 @@ class FakeFileProvider extends FileProvider
|
||||
return $this->temp_files[strtolower($file_path)];
|
||||
}
|
||||
|
||||
if (isset($this->fake_files[$file_path])) {
|
||||
return $this->fake_files[$file_path];
|
||||
}
|
||||
|
||||
return parent::getContents($file_path);
|
||||
return $this->fake_files[$file_path] ?? parent::getContents($file_path);
|
||||
}
|
||||
|
||||
public function setContents(string $file_path, string $file_contents): void
|
||||
@ -50,11 +46,7 @@ class FakeFileProvider extends FileProvider
|
||||
|
||||
public function getModifiedTime(string $file_path): int
|
||||
{
|
||||
if (isset($this->fake_file_times[$file_path])) {
|
||||
return $this->fake_file_times[$file_path];
|
||||
}
|
||||
|
||||
return parent::getModifiedTime($file_path);
|
||||
return $this->fake_file_times[$file_path] ?? parent::getModifiedTime($file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -818,10 +818,7 @@ class FileReferenceCacheProvider
|
||||
if ($cache_directory
|
||||
&& file_exists($config_hash_cache_location)
|
||||
) {
|
||||
/** @var string */
|
||||
$file_maps_cache = file_get_contents($config_hash_cache_location);
|
||||
|
||||
return $file_maps_cache;
|
||||
return file_get_contents($config_hash_cache_location);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -78,7 +78,7 @@ class FileReferenceProvider
|
||||
*
|
||||
* @var array<int, string>|null
|
||||
*/
|
||||
private static $deleted_files = null;
|
||||
private static $deleted_files;
|
||||
|
||||
/**
|
||||
* A lookup table used for getting all the files referenced by a file
|
||||
@ -447,7 +447,7 @@ class FileReferenceProvider
|
||||
*/
|
||||
public function getFilesReferencingFile(string $file): array
|
||||
{
|
||||
return isset(self::$file_references[$file]['a']) ? self::$file_references[$file]['a'] : [];
|
||||
return self::$file_references[$file]['a'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -455,7 +455,7 @@ class FileReferenceProvider
|
||||
*/
|
||||
public function getFilesInheritingFromFile(string $file): array
|
||||
{
|
||||
return isset(self::$file_references[$file]['i']) ? self::$file_references[$file]['i'] : [];
|
||||
return self::$file_references[$file]['i'] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -691,14 +691,14 @@ class FileReferenceProvider
|
||||
foreach ($visited_files as $file => $_) {
|
||||
$all_file_references = array_unique(
|
||||
array_merge(
|
||||
isset(self::$file_references[$file]['a']) ? self::$file_references[$file]['a'] : [],
|
||||
self::$file_references[$file]['a'] ?? [],
|
||||
$this->calculateFilesReferencingFile($codebase, $file)
|
||||
)
|
||||
);
|
||||
|
||||
$inheritance_references = array_unique(
|
||||
array_merge(
|
||||
isset(self::$file_references[$file]['i']) ? self::$file_references[$file]['i'] : [],
|
||||
self::$file_references[$file]['i'] ?? [],
|
||||
$this->calculateFilesInheritingFile($codebase, $file)
|
||||
)
|
||||
);
|
||||
|
@ -45,7 +45,7 @@ class ParserCacheProvider
|
||||
*
|
||||
* @var array<string, string>|null
|
||||
*/
|
||||
private $existing_file_content_hashes = null;
|
||||
private $existing_file_content_hashes;
|
||||
|
||||
/**
|
||||
* A map of recently-added filename hashes to contents hashes
|
||||
|
@ -21,12 +21,12 @@ class ProjectCacheProvider
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private $last_run = null;
|
||||
private $last_run;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $composer_lock_hash = null;
|
||||
private $composer_lock_hash;
|
||||
|
||||
private $composer_lock_location;
|
||||
|
||||
|
@ -38,7 +38,7 @@ class ArrayFilterReturnTypeProvider implements \Psalm\Plugin\EventHandler\Functi
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$array_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;
|
||||
$array_arg = $call_args[0]->value ?? null;
|
||||
|
||||
$first_arg_array = $array_arg
|
||||
&& ($first_arg_type = $statements_source->node_data->getType($array_arg))
|
||||
|
@ -24,7 +24,7 @@ class ArrayPointerAdjustmentReturnTypeProvider implements \Psalm\Plugin\EventHan
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$first_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;
|
||||
$first_arg = $call_args[0]->value ?? null;
|
||||
|
||||
if (!$first_arg) {
|
||||
return Type::getMixed();
|
||||
|
@ -23,7 +23,7 @@ class ArrayPopReturnTypeProvider implements \Psalm\Plugin\EventHandler\FunctionR
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$first_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;
|
||||
$first_arg = $call_args[0]->value ?? null;
|
||||
|
||||
$first_arg_array = $first_arg
|
||||
&& ($first_arg_type = $statements_source->node_data->getType($first_arg))
|
||||
|
@ -23,8 +23,8 @@ class ArrayRandReturnTypeProvider implements \Psalm\Plugin\EventHandler\Function
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$first_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;
|
||||
$second_arg = isset($call_args[1]->value) ? $call_args[1]->value : null;
|
||||
$first_arg = $call_args[0]->value ?? null;
|
||||
$second_arg = $call_args[1]->value ?? null;
|
||||
|
||||
$first_arg_array = $first_arg
|
||||
&& ($first_arg_type = $statements_source->node_data->getType($first_arg))
|
||||
|
@ -258,11 +258,6 @@ class ArrayReduceReturnTypeProvider implements \Psalm\Plugin\EventHandler\Functi
|
||||
$method_id,
|
||||
$self_class
|
||||
) ?: Type::getMixed();
|
||||
|
||||
$reduce_return_type = Type::combineUnionTypes(
|
||||
$reduce_return_type,
|
||||
$return_type
|
||||
);
|
||||
} else {
|
||||
if (!$codebase->functions->functionExists(
|
||||
$statements_source,
|
||||
@ -280,12 +275,9 @@ class ArrayReduceReturnTypeProvider implements \Psalm\Plugin\EventHandler\Functi
|
||||
);
|
||||
|
||||
$return_type = $function_storage->return_type ?: Type::getMixed();
|
||||
|
||||
$reduce_return_type = Type::combineUnionTypes(
|
||||
$reduce_return_type,
|
||||
$return_type
|
||||
);
|
||||
}
|
||||
|
||||
$reduce_return_type = Type::combineUnionTypes($reduce_return_type, $return_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ class ArraySliceReturnTypeProvider implements \Psalm\Plugin\EventHandler\Functio
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$first_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;
|
||||
$first_arg = $call_args[0]->value ?? null;
|
||||
|
||||
if (!$first_arg) {
|
||||
return Type::getArray();
|
||||
|
@ -22,7 +22,7 @@ class ArrayValuesReturnTypeProvider implements \Psalm\Plugin\EventHandler\Functi
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$first_arg = isset($call_args[0]->value) ? $call_args[0]->value : null;
|
||||
$first_arg = $call_args[0]->value ?? null;
|
||||
|
||||
if (!$first_arg) {
|
||||
return Type::getArray();
|
||||
|
@ -14,7 +14,7 @@ use function count;
|
||||
use function filemtime;
|
||||
use function md5;
|
||||
use function strlen;
|
||||
use function substr;
|
||||
use function strpos;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -227,7 +227,7 @@ class StatementsProvider
|
||||
|
||||
$changed_members = array_map(
|
||||
function (string $key) use ($file_path_hash) : string {
|
||||
if (substr($key, 0, 4) === 'use:') {
|
||||
if (strpos($key, 'use:') === 0) {
|
||||
return $key . ':' . $file_path_hash;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class ClassLikeDocblockComment
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
public $psalm_internal = null;
|
||||
public $psalm_internal;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
@ -57,7 +57,7 @@ class ClassLikeDocblockComment
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
public $yield = null;
|
||||
public $yield;
|
||||
|
||||
/**
|
||||
* @var array<int, array{name:string, type:string, tag:string, line_number:int}>
|
||||
|
@ -31,7 +31,7 @@ class DocblockParser
|
||||
// Strip off comments.
|
||||
$docblock = trim($docblock);
|
||||
|
||||
if (substr($docblock, 0, 3) === '/**') {
|
||||
if (strpos($docblock, '/**') === 0) {
|
||||
$docblock = substr($docblock, 3);
|
||||
}
|
||||
|
||||
|
@ -9,22 +9,22 @@ class FunctionDocblockComment
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $return_type = null;
|
||||
public $return_type;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $return_type_description = null;
|
||||
public $return_type_description;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
public $return_type_start = null;
|
||||
public $return_type_start;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
public $return_type_end = null;
|
||||
public $return_type_end;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
@ -73,7 +73,7 @@ class FunctionDocblockComment
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
public $psalm_internal = null;
|
||||
public $psalm_internal;
|
||||
|
||||
/**
|
||||
* Whether or not the function is internal
|
||||
|
@ -9,8 +9,11 @@ use Psalm\Internal\Scanner\UnresolvedConstantComponent;
|
||||
*/
|
||||
class UnresolvedTernary extends UnresolvedConstantComponent
|
||||
{
|
||||
/** @var UnresolvedConstantComponent */
|
||||
public $cond;
|
||||
/** @var UnresolvedConstantComponent|null */
|
||||
public $if;
|
||||
/** @var UnresolvedConstantComponent */
|
||||
public $else;
|
||||
|
||||
public function __construct(
|
||||
|
@ -16,7 +16,7 @@ class VarDocblockComment
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $var_id = null;
|
||||
public $var_id;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
@ -52,7 +52,7 @@ class VarDocblockComment
|
||||
*
|
||||
* @var null|string
|
||||
*/
|
||||
public $psalm_internal = null;
|
||||
public $psalm_internal;
|
||||
|
||||
/**
|
||||
* Whether or not the property is readonly
|
||||
|
@ -12,7 +12,7 @@ class IfScope
|
||||
/**
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $new_vars = null;
|
||||
public $new_vars;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
@ -22,12 +22,12 @@ class IfScope
|
||||
/**
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $redefined_vars = null;
|
||||
public $redefined_vars;
|
||||
|
||||
/**
|
||||
* @var array<string, int>|null
|
||||
*/
|
||||
public $assigned_var_ids = null;
|
||||
public $assigned_var_ids;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
@ -57,7 +57,7 @@ class IfScope
|
||||
/**
|
||||
* @var array<string, string>|null
|
||||
*/
|
||||
public $negatable_if_types = null;
|
||||
public $negatable_if_types;
|
||||
|
||||
/**
|
||||
* @var list<Clause>
|
||||
@ -78,7 +78,7 @@ class IfScope
|
||||
*
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $possible_param_types = null;
|
||||
public $possible_param_types;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
|
@ -37,7 +37,7 @@ class LoopScope
|
||||
/**
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $possibly_redefined_loop_parent_vars = null;
|
||||
public $possibly_redefined_loop_parent_vars;
|
||||
|
||||
/**
|
||||
* @var array<string, Type\Union>
|
||||
|
@ -13,7 +13,7 @@ class SwitchScope
|
||||
/**
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $new_vars_in_scope = null;
|
||||
public $new_vars_in_scope;
|
||||
|
||||
/**
|
||||
* @var array<string, bool>
|
||||
@ -23,12 +23,12 @@ class SwitchScope
|
||||
/**
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $redefined_vars = null;
|
||||
public $redefined_vars;
|
||||
|
||||
/**
|
||||
* @var array<string, Type\Union>|null
|
||||
*/
|
||||
public $possibly_redefined_vars = null;
|
||||
public $possibly_redefined_vars;
|
||||
|
||||
/**
|
||||
* @var array<PhpParser\Node\Stmt>
|
||||
@ -38,7 +38,7 @@ class SwitchScope
|
||||
/**
|
||||
* @var PhpParser\Node\Expr|null
|
||||
*/
|
||||
public $leftover_case_equality_expr = null;
|
||||
public $leftover_case_equality_expr;
|
||||
|
||||
/**
|
||||
* @var list<Clause>
|
||||
@ -48,5 +48,5 @@ class SwitchScope
|
||||
/**
|
||||
* @var array<string, bool>|null
|
||||
*/
|
||||
public $new_assigned_var_ids = null;
|
||||
public $new_assigned_var_ids;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use Psalm\Storage\ClassLikeStorage;
|
||||
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
|
||||
use Psalm\Internal\Scanner\ParsedDocblock;
|
||||
use Psalm\Type;
|
||||
use function array_slice;
|
||||
|
||||
class ClassLikeStubGenerator
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ use Psalm\Node\VirtualName;
|
||||
use Psalm\Node\VirtualNullableType;
|
||||
use Psalm\Node\VirtualParam;
|
||||
use Psalm\Type;
|
||||
use function dirname;
|
||||
|
||||
class StubsGenerator
|
||||
{
|
||||
|
@ -147,7 +147,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
return $simply_reconciled_type;
|
||||
}
|
||||
|
||||
if (substr($assertion, 0, 4) === 'isa-') {
|
||||
if (strpos($assertion, 'isa-') === 0) {
|
||||
$should_return = false;
|
||||
|
||||
$new_type = self::handleIsA(
|
||||
@ -164,7 +164,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
if ($should_return) {
|
||||
return $new_type;
|
||||
}
|
||||
} elseif (substr($assertion, 0, 9) === 'getclass-') {
|
||||
} elseif (strpos($assertion, 'getclass-') === 0) {
|
||||
$assertion = substr($assertion, 9);
|
||||
$new_type = Type::parseString($assertion, null, $template_type_map);
|
||||
} else {
|
||||
@ -1003,7 +1003,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
$did_remove_type = false;
|
||||
|
||||
foreach ($existing_var_atomic_types as $atomic_key => $_) {
|
||||
if (substr($atomic_key, 0, 6) === 'float(') {
|
||||
if (strpos($atomic_key, 'float(') === 0) {
|
||||
$atomic_key = 'int(' . substr($atomic_key, 6);
|
||||
}
|
||||
if ($atomic_key !== $assertion) {
|
||||
@ -1075,7 +1075,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
$existing_var_atomic_type->as = self::handleLiteralEquality(
|
||||
$assertion,
|
||||
$bracket_pos,
|
||||
$is_loose_equality,
|
||||
false,
|
||||
$existing_var_atomic_type->as,
|
||||
$old_var_type_string,
|
||||
$var_id,
|
||||
@ -1211,7 +1211,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
$did_remove_type = false;
|
||||
|
||||
foreach ($existing_var_atomic_types as $atomic_key => $_) {
|
||||
if (substr($atomic_key, 0, 4) === 'int(') {
|
||||
if (strpos($atomic_key, 'int(') === 0) {
|
||||
$atomic_key = 'float(' . substr($atomic_key, 4);
|
||||
}
|
||||
if ($atomic_key !== $assertion) {
|
||||
@ -1240,7 +1240,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
}
|
||||
}
|
||||
} elseif ($scalar_type === 'enum') {
|
||||
list($fq_enum_name, $case_name) = explode('::', $value);
|
||||
[$fq_enum_name, $case_name] = explode('::', $value);
|
||||
|
||||
if ($existing_var_type->hasMixed()) {
|
||||
if ($is_loose_equality) {
|
||||
@ -1297,7 +1297,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
Codebase $codebase,
|
||||
Union $existing_var_type,
|
||||
string &$assertion,
|
||||
array &$template_type_map,
|
||||
array $template_type_map,
|
||||
?CodeLocation $code_location,
|
||||
?string $key,
|
||||
array $suppressed_issues,
|
||||
@ -1307,7 +1307,7 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
|
||||
$allow_string_comparison = false;
|
||||
|
||||
if (substr($assertion, 0, 7) === 'string-') {
|
||||
if (strpos($assertion, 'string-') === 0) {
|
||||
$assertion = substr($assertion, 7);
|
||||
$allow_string_comparison = true;
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ class CallableTypeComparator
|
||||
|
||||
$matching_callable->is_pure = $codebase->functions->isCallMapFunctionPure(
|
||||
$codebase,
|
||||
$statements_analyzer ? $statements_analyzer->node_data : null,
|
||||
$statements_analyzer->node_data ?? null,
|
||||
$input_type_part->value,
|
||||
null,
|
||||
$must_use
|
||||
|
@ -81,15 +81,7 @@ class IntegerRangeComparator
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($result_reduction === null) {
|
||||
//inconclusive result, we can't remove atomics anymore.
|
||||
//container: `int<1, 5>`, input: `int<0, 6>`
|
||||
//container: `5`, input: `int<4, 6>`
|
||||
//we assume there's no combinations that makes the input contained
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result_reduction;
|
||||
return $result_reduction ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,11 +76,11 @@ class ObjectComparator
|
||||
|
||||
foreach ($intersection_input_types as $intersection_input_type) {
|
||||
if ($intersection_input_type instanceof TTemplateParam
|
||||
&& (\substr($intersection_container_type->defining_class, 0, 3) === 'fn-'
|
||||
|| \substr($intersection_input_type->defining_class, 0, 3) === 'fn-')
|
||||
&& (\strpos($intersection_container_type->defining_class, 'fn-') === 0
|
||||
|| \strpos($intersection_input_type->defining_class, 'fn-') === 0)
|
||||
) {
|
||||
if (\substr($intersection_input_type->defining_class, 0, 3) === 'fn-'
|
||||
&& \substr($intersection_container_type->defining_class, 0, 3) === 'fn-'
|
||||
if (\strpos($intersection_input_type->defining_class, 'fn-') === 0
|
||||
&& \strpos($intersection_container_type->defining_class, 'fn-') === 0
|
||||
&& $intersection_input_type->defining_class
|
||||
!== $intersection_container_type->defining_class
|
||||
) {
|
||||
@ -191,10 +191,10 @@ class ObjectComparator
|
||||
if ($intersection_container_type->param_name !== $intersection_input_type->param_name
|
||||
|| ($intersection_container_type->defining_class
|
||||
!== $intersection_input_type->defining_class
|
||||
&& \substr($intersection_input_type->defining_class, 0, 3) !== 'fn-'
|
||||
&& \substr($intersection_container_type->defining_class, 0, 3) !== 'fn-')
|
||||
&& \strpos($intersection_input_type->defining_class, 'fn-') !== 0
|
||||
&& \strpos($intersection_container_type->defining_class, 'fn-') !== 0)
|
||||
) {
|
||||
if (\substr($intersection_input_type->defining_class, 0, 3) !== 'fn-') {
|
||||
if (\strpos($intersection_input_type->defining_class, 'fn-') !== 0) {
|
||||
$input_class_storage = $codebase->classlike_storage_provider->get(
|
||||
$intersection_input_type->defining_class
|
||||
);
|
||||
|
@ -5,26 +5,26 @@ namespace Psalm\Internal\Type\Comparator;
|
||||
class TypeComparisonResult
|
||||
{
|
||||
/** @var ?bool */
|
||||
public $scalar_type_match_found = null;
|
||||
public $scalar_type_match_found;
|
||||
|
||||
/** @var ?bool */
|
||||
public $type_coerced = null;
|
||||
public $type_coerced;
|
||||
|
||||
/** @var ?bool */
|
||||
public $type_coerced_from_mixed = null;
|
||||
public $type_coerced_from_mixed;
|
||||
|
||||
/** @var ?bool */
|
||||
public $type_coerced_from_as_mixed = null;
|
||||
public $type_coerced_from_as_mixed;
|
||||
|
||||
/** @var ?bool */
|
||||
public $to_string_cast = null;
|
||||
public $to_string_cast;
|
||||
|
||||
/** @var ?bool */
|
||||
public $type_coerced_from_scalar = null;
|
||||
public $type_coerced_from_scalar;
|
||||
|
||||
/** @var ?\Psalm\Type\Union */
|
||||
public $replacement_union_type = null;
|
||||
public $replacement_union_type;
|
||||
|
||||
/** @var ?\Psalm\Type\Atomic */
|
||||
public $replacement_atomic_type = null;
|
||||
public $replacement_atomic_type;
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ class UnionTypeComparator
|
||||
}
|
||||
}
|
||||
|
||||
return !!$matching_input_keys;
|
||||
return (bool)$matching_input_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -159,7 +159,7 @@ class NegatedAssertionReconciler extends Reconciler
|
||||
return Type::getEmpty();
|
||||
}
|
||||
|
||||
if (substr($assertion, 0, 9) === 'in-array-') {
|
||||
if (strpos($assertion, 'in-array-') === 0) {
|
||||
$assertion = substr($assertion, 9);
|
||||
$new_var_type = null;
|
||||
try {
|
||||
@ -195,7 +195,7 @@ class NegatedAssertionReconciler extends Reconciler
|
||||
return $existing_var_type;
|
||||
}
|
||||
|
||||
if (substr($assertion, 0, 14) === 'has-array-key-') {
|
||||
if (strpos($assertion, 'has-array-key-') === 0) {
|
||||
return $existing_var_type;
|
||||
}
|
||||
}
|
||||
@ -283,7 +283,7 @@ class NegatedAssertionReconciler extends Reconciler
|
||||
) {
|
||||
$existing_var_type->removeType('array-key');
|
||||
$existing_var_type->addType(new TString);
|
||||
} elseif (substr($assertion, 0, 9) === 'getclass-') {
|
||||
} elseif (strpos($assertion, 'getclass-') === 0) {
|
||||
$assertion = substr($assertion, 9);
|
||||
} elseif (!$is_equality) {
|
||||
$codebase = $statements_analyzer->getCodebase();
|
||||
@ -462,7 +462,7 @@ class NegatedAssertionReconciler extends Reconciler
|
||||
$scalar_var_type = Type::getFloat((float) $scalar_value);
|
||||
}
|
||||
} elseif ($scalar_type === 'enum') {
|
||||
list($fq_enum_name, $case_name) = explode('::', substr($assertion, $bracket_pos + 1, -1));
|
||||
[$fq_enum_name, $case_name] = explode('::', substr($assertion, $bracket_pos + 1, -1));
|
||||
|
||||
foreach ($existing_var_type->getAtomicTypes() as $atomic_key => $atomic_type) {
|
||||
if (get_class($atomic_type) === Type\Atomic\TNamedObject::class
|
||||
|
@ -402,10 +402,8 @@ class ParseTreeCreator
|
||||
$this->current_leaf->parent = $new_leaf;
|
||||
|
||||
array_pop($current_parent->children);
|
||||
$current_parent->children[] = $new_leaf;
|
||||
} else {
|
||||
$current_parent->children[] = $new_leaf;
|
||||
}
|
||||
$current_parent->children[] = $new_leaf;
|
||||
|
||||
$this->current_leaf = $new_leaf;
|
||||
}
|
||||
@ -450,7 +448,7 @@ class ParseTreeCreator
|
||||
return;
|
||||
}
|
||||
|
||||
if ($current_parent && $current_parent instanceof ParseTree\KeyedArrayPropertyTree) {
|
||||
if ($current_parent instanceof ParseTree\KeyedArrayPropertyTree) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -462,7 +460,7 @@ class ParseTreeCreator
|
||||
$current_parent = $this->current_leaf->parent;
|
||||
}
|
||||
|
||||
if ($current_parent && $current_parent instanceof ParseTree\ConditionalTree) {
|
||||
if ($current_parent instanceof ParseTree\ConditionalTree) {
|
||||
if (count($current_parent->children) > 1) {
|
||||
throw new TypeParseTreeException('Cannot process colon in conditional twice');
|
||||
}
|
||||
@ -608,12 +606,12 @@ class ParseTreeCreator
|
||||
throw new TypeParseTreeException('Unexpected token |');
|
||||
}
|
||||
|
||||
if ($current_parent && $current_parent instanceof ParseTree\UnionTree) {
|
||||
if ($current_parent instanceof ParseTree\UnionTree) {
|
||||
$this->current_leaf = $current_parent;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($current_parent && $current_parent instanceof ParseTree\IntersectionTree) {
|
||||
if ($current_parent instanceof ParseTree\IntersectionTree) {
|
||||
$this->current_leaf = $current_parent;
|
||||
$current_parent = $this->current_leaf->parent;
|
||||
}
|
||||
@ -649,12 +647,12 @@ class ParseTreeCreator
|
||||
|
||||
$current_parent = $this->current_leaf->parent;
|
||||
|
||||
if ($current_parent && $current_parent instanceof ParseTree\MethodTree) {
|
||||
if ($current_parent instanceof ParseTree\MethodTree) {
|
||||
$this->createMethodParam($this->type_tokens[$this->t], $current_parent);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($current_parent && $current_parent instanceof ParseTree\IntersectionTree) {
|
||||
if ($current_parent instanceof ParseTree\IntersectionTree) {
|
||||
$this->current_leaf = $current_parent;
|
||||
return;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user