1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-13 01:37:23 +01:00

Merge pull request #6532 from orklah/code-trimming

code trimming
This commit is contained in:
orklah 2021-09-25 02:49:48 +02:00 committed by GitHub
commit f86e3b1bf9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 302 additions and 279 deletions

View File

@ -942,26 +942,21 @@ class Codebase
return null;
}
$storage = $this->methods->getStorage($declaring_method_id);
return $storage;
return $this->methods->getStorage($declaring_method_id);
}
$function_id = strtolower(substr($symbol, 0, -2));
$file_storage = $this->file_storage_provider->get($file_path);
if (isset($file_storage->functions[$function_id])) {
$function_storage = $file_storage->functions[$function_id];
return $function_storage;
return $file_storage->functions[$function_id];
}
if (!$function_id) {
return null;
}
$function = $this->functions->getStorage(null, $function_id);
return $function;
return $this->functions->getStorage(null, $function_id);
}
/**
@ -1166,13 +1161,10 @@ class Codebase
return null;
}
$function = $this->functions->getStorage(null, $function_id);
return $function->location;
return $this->functions->getStorage(null, $function_id)->location;
}
$storage = $this->classlike_storage_provider->get($symbol);
return $storage->location;
return $this->classlike_storage_provider->get($symbol)->location;
} catch (\UnexpectedValueException $e) {
error_log($e->getMessage());
@ -1477,8 +1469,8 @@ class Codebase
if (!$function_storage || !$function_storage->params) {
return null;
}
$parameter = $function_storage->params[$argument_num];
return $parameter->type;
return $function_storage->params[$argument_num]->type;
}
return null;

View File

@ -57,8 +57,6 @@ class FileBasedPluginAdapter implements Plugin\PluginEntryPointInterface
$declared_classes = ClassLikeAnalyzer::getClassesForFile($codebase, $path);
$fq_class_name = reset($declared_classes);
return $fq_class_name;
return reset($declared_classes);
}
}

View File

@ -1036,7 +1036,7 @@ class ClassAnalyzer extends ClassLikeAnalyzer
continue;
}
if ($property->type && $property->type->isNullable() && $property->type->from_docblock) {
if ($property->type && $property->type->from_docblock && $property->type->isNullable()) {
continue;
}
@ -1359,131 +1359,131 @@ class ClassAnalyzer extends ClassLikeAnalyzer
}
return false;
} else {
if (!$codebase->traitHasCorrectCase($fq_trait_name)) {
}
if (!$codebase->traitHasCorrectCase($fq_trait_name)) {
if (IssueBuffer::accepts(
new UndefinedTrait(
'Trait ' . $fq_trait_name . ' has wrong casing',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
return false;
}
continue;
}
$fq_trait_name_resolved = $codebase->classlikes->getUnAliasedName($fq_trait_name);
$trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name_resolved);
if ($trait_storage->deprecated) {
if (IssueBuffer::accepts(
new DeprecatedTrait(
'Trait ' . $fq_trait_name . ' is deprecated',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
if ($trait_storage->extension_requirement !== null) {
$extension_requirement = $codebase->classlikes->getUnAliasedName(
$trait_storage->extension_requirement
);
$extensionRequirementMet = in_array($extension_requirement, $storage->parent_classes);
if (!$extensionRequirementMet) {
if (IssueBuffer::accepts(
new UndefinedTrait(
'Trait ' . $fq_trait_name . ' has wrong casing',
new ExtensionRequirementViolation(
$fq_trait_name . ' requires using class to extend ' . $extension_requirement
. ', but ' . $storage->name . ' does not',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
}
foreach ($trait_storage->implementation_requirements as $implementation_requirement) {
$implementation_requirement = $codebase->classlikes->getUnAliasedName($implementation_requirement);
$implementationRequirementMet = in_array($implementation_requirement, $storage->class_implements);
if (!$implementationRequirementMet) {
if (IssueBuffer::accepts(
new ImplementationRequirementViolation(
$fq_trait_name . ' requires using class to implement '
. $implementation_requirement . ', but ' . $storage->name . ' does not',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
}
if ($storage->mutation_free && !$trait_storage->mutation_free) {
if (IssueBuffer::accepts(
new MutableDependency(
$storage->name . ' is marked @psalm-immutable but ' . $fq_trait_name . ' is not',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
$trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name_resolved);
$trait_node = $codebase->classlikes->getTraitNode($fq_trait_name_resolved);
$trait_aliases = $trait_storage->aliases;
if ($trait_aliases === null) {
continue;
}
$trait_analyzer = new TraitAnalyzer(
$trait_node,
$trait_file_analyzer,
$fq_trait_name_resolved,
$trait_aliases
);
foreach ($trait_node->stmts as $trait_stmt) {
if ($trait_stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
$trait_method_analyzer = $this->analyzeClassMethod(
$trait_stmt,
$storage,
$trait_analyzer,
$class_context,
$global_context
);
if ($trait_stmt->name->name === '__construct') {
$constructor_analyzer = $trait_method_analyzer;
}
} elseif ($trait_stmt instanceof PhpParser\Node\Stmt\TraitUse) {
if ($this->analyzeTraitUse(
$trait_aliases,
$trait_stmt,
$project_analyzer,
$storage,
$class_context,
$global_context,
$constructor_analyzer,
$trait_analyzer
) === false) {
return false;
}
continue;
}
$fq_trait_name_resolved = $codebase->classlikes->getUnAliasedName($fq_trait_name);
$trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name_resolved);
if ($trait_storage->deprecated) {
if (IssueBuffer::accepts(
new DeprecatedTrait(
'Trait ' . $fq_trait_name . ' is deprecated',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
if ($trait_storage->extension_requirement !== null) {
$extension_requirement = $codebase->classlikes->getUnAliasedName(
$trait_storage->extension_requirement
);
$extensionRequirementMet = in_array($extension_requirement, $storage->parent_classes);
if (!$extensionRequirementMet) {
if (IssueBuffer::accepts(
new ExtensionRequirementViolation(
$fq_trait_name . ' requires using class to extend ' . $extension_requirement
. ', but ' . $storage->name . ' does not',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
}
foreach ($trait_storage->implementation_requirements as $implementation_requirement) {
$implementation_requirement = $codebase->classlikes->getUnAliasedName($implementation_requirement);
$implementationRequirementMet = in_array($implementation_requirement, $storage->class_implements);
if (!$implementationRequirementMet) {
if (IssueBuffer::accepts(
new ImplementationRequirementViolation(
$fq_trait_name . ' requires using class to implement '
. $implementation_requirement . ', but ' . $storage->name . ' does not',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
}
if ($storage->mutation_free && !$trait_storage->mutation_free) {
if (IssueBuffer::accepts(
new MutableDependency(
$storage->name . ' is marked @psalm-immutable but ' . $fq_trait_name . ' is not',
new CodeLocation($previous_trait_analyzer ?: $this, $trait_name)
),
$storage->suppressed_issues + $this->getSuppressedIssues()
)) {
// fall through
}
}
$trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name_resolved);
$trait_node = $codebase->classlikes->getTraitNode($fq_trait_name_resolved);
$trait_aliases = $trait_storage->aliases;
if ($trait_aliases === null) {
continue;
}
$trait_analyzer = new TraitAnalyzer(
$trait_node,
$trait_file_analyzer,
$fq_trait_name_resolved,
$trait_aliases
);
foreach ($trait_node->stmts as $trait_stmt) {
if ($trait_stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
$trait_method_analyzer = $this->analyzeClassMethod(
$trait_stmt,
$storage,
$trait_analyzer,
$class_context,
$global_context
);
if ($trait_stmt->name->name === '__construct') {
$constructor_analyzer = $trait_method_analyzer;
}
} elseif ($trait_stmt instanceof PhpParser\Node\Stmt\TraitUse) {
if ($this->analyzeTraitUse(
$trait_aliases,
$trait_stmt,
$project_analyzer,
$storage,
$class_context,
$global_context,
$constructor_analyzer,
$trait_analyzer
) === false) {
return false;
}
}
}
$trait_file_analyzer->clearSourceBeforeDestruction();
}
$trait_file_analyzer->clearSourceBeforeDestruction();
}
$class_context->include_location = $previous_context_include_location;

View File

@ -130,7 +130,7 @@ class ClosureAnalyzer extends FunctionLikeAnalyzer
// insert the ref into the current context if passed by ref, as whatever we're passing
// the closure to could execute it straight away.
if (!$context->hasVariable($use_var_id) && $use->byRef) {
if ($use->byRef && !$context->hasVariable($use_var_id)) {
$context->vars_in_scope[$use_var_id] = Type::getMixed();
}

View File

@ -312,23 +312,30 @@ class ReturnTypeCollector
}
return [Type::getMixed()];
} elseif ($stmt instanceof PhpParser\Node\Expr\YieldFrom) {
}
if ($stmt instanceof PhpParser\Node\Expr\YieldFrom) {
if ($stmt_expr_type = $nodes->getType($stmt->expr)) {
return [$stmt_expr_type];
}
return [Type::getMixed()];
} elseif ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
}
if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
return array_merge(
self::getYieldTypeFromExpression($stmt->left, $nodes),
self::getYieldTypeFromExpression($stmt->right, $nodes)
);
} elseif ($stmt instanceof PhpParser\Node\Expr\Assign) {
}
if ($stmt instanceof PhpParser\Node\Expr\Assign) {
return self::getYieldTypeFromExpression($stmt->expr, $nodes);
} elseif ($stmt instanceof PhpParser\Node\Expr\MethodCall
}
if ($stmt instanceof PhpParser\Node\Expr\MethodCall
|| $stmt instanceof PhpParser\Node\Expr\FuncCall
|| $stmt instanceof PhpParser\Node\Expr\StaticCall
) {
|| $stmt instanceof PhpParser\Node\Expr\StaticCall) {
$yield_types = [];
foreach ($stmt->args as $arg) {

View File

@ -86,9 +86,7 @@ class ScopeAnalyzer
$control_actions = [];
for ($i = 0, $c = count($stmts); $i < $c; ++$i) {
$stmt = $stmts[$i];
foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Return_ ||
$stmt instanceof PhpParser\Node\Stmt\Throw_ ||
($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Exit_)

View File

@ -95,11 +95,7 @@ class ForAnalyzer
foreach ($stmt->cond as $cond) {
if ($cond_type = $statements_analyzer->node_data->getType($cond)) {
foreach ($cond_type->getAtomicTypes() as $iterator_type) {
$always_enters_loop = $iterator_type instanceof Type\Atomic\TTrue;
break;
}
$always_enters_loop = $cond_type->isAlwaysTruthy();
}
if (\count($stmt->init) === 1

View File

@ -369,7 +369,9 @@ class ForeachAnalyzer
}
return false;
} elseif ($iterator_type->isNullable() && !$iterator_type->ignore_nullable_issues) {
}
if ($iterator_type->isNullable() && !$iterator_type->ignore_nullable_issues) {
if (IssueBuffer::accepts(
new PossiblyNullIterator(
'Cannot iterate over nullable var ' . $iterator_type,

View File

@ -1155,9 +1155,10 @@ class AssertionFinder
}
return [$instanceof_class];
} elseif ($this_class_name
&& (in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], true))
) {
}
if ($this_class_name
&& (in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], true))) {
if ($stmt->class->parts[0] === 'static') {
return ['=' . $this_class_name . '&static'];
}

View File

@ -616,7 +616,7 @@ class InstancePropertyAssignmentAnalyzer
Context $context,
bool $direct_assignment,
\Psalm\Codebase $codebase,
Type\Union &$assignment_value_type,
Type\Union $assignment_value_type,
string $prop_name,
?string &$var_id
): array {

View File

@ -11,6 +11,7 @@ use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\Functions;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
@ -476,7 +477,7 @@ class ArgumentsAnalyzer
if ($function_storage) {
$is_variadic = $function_storage->variadic;
} elseif (is_string($method_id)) {
$is_variadic = $codebase->functions->isVariadic(
$is_variadic = Functions::isVariadic(
$codebase,
strtolower($method_id),
$statements_analyzer->getRootFilePath()

View File

@ -770,7 +770,9 @@ class ArrayFunctionArgumentsAnalyzer
}
return;
} elseif ($required_param_count > $max_closure_param_count) {
}
if ($required_param_count > $max_closure_param_count) {
$argument_text = $max_closure_param_count === 1 ? 'one argument' : $max_closure_param_count . ' arguments';
if (IssueBuffer::accepts(

View File

@ -434,9 +434,9 @@ class FunctionCallAnalyzer extends CallAnalyzer
}
return $function_call_info;
} else {
$function_call_info->function_exists = true;
}
$function_call_info->function_exists = true;
}
} else {
$function_call_info->function_exists = true;

View File

@ -169,14 +169,15 @@ class ExpressionIdentifier
if ($stmt->name instanceof PhpParser\Node\Identifier) {
return $object_id . '->' . $stmt->name;
} elseif ($source instanceof StatementsAnalyzer
&& ($stmt_name_type = $source->node_data->getType($stmt->name))
&& $stmt_name_type->isSingleStringLiteral()
) {
return $object_id . '->' . $stmt_name_type->getSingleStringLiteral()->value;
} else {
return null;
}
if ($source instanceof StatementsAnalyzer
&& ($stmt_name_type = $source->node_data->getType($stmt->name))
&& $stmt_name_type->isSingleStringLiteral()) {
return $object_id . '->' . $stmt_name_type->getSingleStringLiteral()->value;
}
return null;
}
if ($stmt instanceof PhpParser\Node\Expr\ClassConstFetch

View File

@ -1086,16 +1086,14 @@ class ArrayFetchAnalyzer
}
}
if (!$array_access_type) {
return Type::getMixed(
$type instanceof TEmpty
);
} else {
if ($array_access_type) {
return Type::combineUnionTypes(
$array_access_type,
Type::getMixed($type instanceof TEmpty)
);
}
return Type::getMixed($type instanceof TEmpty);
}
/**

View File

@ -557,9 +557,7 @@ class VariableFetchAnalyzer
}
if (self::isSuperGlobal($var_id)) {
$type = Type::getArray();
return $type;
return Type::getArray();
}
return Type::getMixed();

View File

@ -189,13 +189,20 @@ class SimpleTypeInferer
}
if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
if (strtolower($stmt->name->parts[0]) === 'false') {
$name = strtolower($stmt->name->parts[0]);
if ($name === 'false') {
return Type::getFalse();
} elseif (strtolower($stmt->name->parts[0]) === 'true') {
}
if ($name === 'true') {
return Type::getTrue();
} elseif (strtolower($stmt->name->parts[0]) === 'null') {
}
if ($name === 'null') {
return Type::getNull();
} elseif ($stmt->name->parts[0] === '__NAMESPACE__') {
}
if ($stmt->name->parts[0] === '__NAMESPACE__') {
return Type::getString($aliases->namespace);
}
@ -691,7 +698,9 @@ class SimpleTypeInferer
if ($unpacked_atomic_type->type_params[0]->hasString()) {
// string keys are not supported in unpacked arrays
return false;
} elseif ($unpacked_atomic_type->type_params[0]->hasInt()) {
}
if ($unpacked_atomic_type->type_params[0]->hasInt()) {
$array_creation_info->item_key_atomic_types[] = new Type\Atomic\TInt();
}

View File

@ -215,14 +215,13 @@ class UnusedAssignmentRemover
|| $rhs_exp instanceof PhpParser\Node\Expr\AssignOp
|| $rhs_exp instanceof PhpParser\Node\Expr\AssignRef
) {
$rhs_removable = $this->checkRemovableChainAssignment($rhs_exp, $var_loc_map);
return $rhs_removable;
return $this->checkRemovableChainAssignment($rhs_exp, $var_loc_map);
}
}
return $curr_removable;
} else {
return false;
}
return false;
}
/**
@ -344,9 +343,9 @@ class UnusedAssignmentRemover
$rhs_exp = $current_node->expr;
$rhs_search_result = $this->findAssignExp($rhs_exp, $var_id, $var_start_loc, $search_level + 1);
return [$rhs_search_result[0], $rhs_search_result[1]];
} else {
return [null, $search_level];
}
return [null, $search_level];
}
public function checkIfVarRemoved(string $var_id, CodeLocation $var_loc): bool

View File

@ -10,6 +10,7 @@ use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\CliUtils;
use Psalm\Internal\Composer;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\Fork\PsalmRestarter;
use Psalm\Internal\IncludeCollector;
use Psalm\Internal\Provider;
use Psalm\IssueBuffer;
@ -902,7 +903,7 @@ final class Psalm
// If Xdebug is enabled, restart without it
$ini_handler->check();
if ($config->load_xdebug_stub === null && '' !== $ini_handler->getSkippedVersion()) {
if ($config->load_xdebug_stub === null && PsalmRestarter::getSkippedVersion() !== '') {
$config->load_xdebug_stub = true;
}
}

View File

@ -63,7 +63,7 @@ final class CliUtils
require_once __DIR__ . '/../../../vendor/netresearch/jsonmapper/src/JsonMapper/Exception.php';
}
if (realpath($psalm_dir) !== realpath($current_dir) && !$in_phar) {
if (!$in_phar && realpath($psalm_dir) !== realpath($current_dir)) {
$autoload_roots[] = $psalm_dir;
}
@ -241,13 +241,14 @@ final class CliUtils
/** @var string */
$input_path = $input_paths[$i];
if (realpath($input_path) === realpath(dirname(__DIR__, 5) . DIRECTORY_SEPARATOR . 'bin'
$real_input_path = realpath($input_path);
if ($real_input_path === realpath(dirname(__DIR__, 5) . DIRECTORY_SEPARATOR . 'bin'
. DIRECTORY_SEPARATOR . 'psalm')
|| realpath($input_path) === realpath(dirname(__DIR__, 5) . DIRECTORY_SEPARATOR . 'bin'
|| $real_input_path === realpath(dirname(__DIR__, 5) . DIRECTORY_SEPARATOR . 'bin'
. DIRECTORY_SEPARATOR . 'psalter')
|| realpath($input_path) === realpath(dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'psalm')
|| realpath($input_path) === realpath(dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'psalter')
|| realpath($input_path) === realpath(Phar::running(false))
|| $real_input_path === realpath(dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'psalm')
|| $real_input_path === realpath(dirname(__DIR__, 3) . DIRECTORY_SEPARATOR . 'psalter')
|| $real_input_path === realpath(Phar::running(false))
) {
continue;
}

View File

@ -545,13 +545,8 @@ class ClassLikes
?string $calling_fq_class_name = null,
?string $calling_method_id = null
): bool {
if (!$this->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
&& !$this->interfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
) {
return false;
}
return true;
return $this->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
|| $this->interfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
}
/**
@ -563,14 +558,9 @@ class ClassLikes
?string $calling_fq_class_name = null,
?string $calling_method_id = null
): bool {
if (!$this->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
&& !$this->interfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
&& !$this->enumExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
) {
return false;
}
return true;
return $this->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
|| $this->interfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id)
|| $this->enumExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
}
/**
@ -721,9 +711,7 @@ class ClassLikes
{
$fq_interface_name = strtolower($fq_interface_name);
$storage = $this->classlike_storage_provider->get($fq_interface_name);
return $storage->parent_interfaces;
return $this->classlike_storage_provider->get($fq_interface_name)->parent_interfaces;
}
public function traitExists(string $fq_trait_name, ?CodeLocation $code_location = null): bool

View File

@ -301,16 +301,24 @@ class ConstantTypeResolver
{
if (\is_string($value)) {
return new Type\Atomic\TLiteralString($value);
} elseif (\is_int($value)) {
return new Type\Atomic\TLiteralInt($value);
} elseif (\is_float($value)) {
return new Type\Atomic\TLiteralFloat($value);
} elseif ($value === false) {
return new Type\Atomic\TFalse;
} elseif ($value === true) {
return new Type\Atomic\TTrue;
} else {
return new Type\Atomic\TNull;
}
if (\is_int($value)) {
return new Type\Atomic\TLiteralInt($value);
}
if (\is_float($value)) {
return new Type\Atomic\TLiteralFloat($value);
}
if ($value === false) {
return new Type\Atomic\TFalse;
}
if ($value === true) {
return new Type\Atomic\TTrue;
}
return new Type\Atomic\TNull;
}
}

View File

@ -531,8 +531,7 @@ class Functions
);
try {
$method_storage = $codebase->methods->getStorage($count_method_id);
return $method_storage->mutation_free;
return $codebase->methods->getStorage($count_method_id)->mutation_free;
} catch (\Exception $e) {
// do nothing
}

View File

@ -955,9 +955,7 @@ class Methods
return false;
}
$storage = $this->getStorage($method_id);
return $storage->returns_by_ref;
return $this->getStorage($method_id)->returns_by_ref;
}
/**

View File

@ -147,8 +147,8 @@ class Populator
$this->progress->debug('FileStorage is populated' . "\n");
$this->classlike_storage_provider->populated();
$this->file_storage_provider->populated();
ClassLikeStorageProvider::populated();
FileStorageProvider::populated();
}
private function populateClassLikeStorage(ClassLikeStorage $storage, array $dependent_classlikes = []): void

View File

@ -5,6 +5,7 @@ use Psalm\Codebase;
use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
@ -360,8 +361,8 @@ class Scanner
$statements_provider = $codebase->statements_provider;
$codebase->scanner->isForked();
$codebase->file_storage_provider->deleteAll();
$codebase->classlike_storage_provider->deleteAll();
FileStorageProvider::deleteAll();
ClassLikeStorageProvider::deleteAll();
$statements_provider->resetDiffs();

View File

@ -229,7 +229,7 @@ class FunctionDocblockManipulator
continue;
}
if ($chars[$i] === '\\' || preg_match('/\w/', $char)) {
if ($char === '\\' || preg_match('/\w/', $char)) {
if ($this->return_typehint_start === null) {
$this->return_typehint_start = $i + $end_bracket_position + 1;
}

View File

@ -48,9 +48,9 @@ class CheckTrivialExprVisitor extends PhpParser\NodeVisitorAbstract
}
return true;
} else {
return false;
}
return false;
}
public function enterNode(PhpParser\Node $node): ?int
@ -60,12 +60,13 @@ class CheckTrivialExprVisitor extends PhpParser\NodeVisitorAbstract
if ($this->checkNonTrivialExpr($node)) {
$this->non_trivial_expr[] = $node;
return PhpParser\NodeTraverser::STOP_TRAVERSAL;
} elseif ($node instanceof PhpParser\Node\Expr\ClassConstFetch
}
if ($node instanceof PhpParser\Node\Expr\ClassConstFetch
|| $node instanceof PhpParser\Node\Expr\ConstFetch
|| $node instanceof PhpParser\Node\Expr\Error
|| $node instanceof PhpParser\Node\Expr\PropertyFetch
|| $node instanceof PhpParser\Node\Expr\StaticPropertyFetch
) {
|| $node instanceof PhpParser\Node\Expr\StaticPropertyFetch) {
return PhpParser\NodeTraverser::STOP_TRAVERSAL;
}
}

View File

@ -117,11 +117,17 @@ class ExpressionResolver
if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
if (strtolower($stmt->name->parts[0]) === 'false') {
return new UnresolvedConstant\ScalarValue(false);
} elseif (strtolower($stmt->name->parts[0]) === 'true') {
}
if (strtolower($stmt->name->parts[0]) === 'true') {
return new UnresolvedConstant\ScalarValue(true);
} elseif (strtolower($stmt->name->parts[0]) === 'null') {
}
if (strtolower($stmt->name->parts[0]) === 'null') {
return new UnresolvedConstant\ScalarValue(null);
} elseif ($stmt->name->parts[0] === '__NAMESPACE__') {
}
if ($stmt->name->parts[0] === '__NAMESPACE__') {
return new UnresolvedConstant\ScalarValue($aliases->namespace);
}

View File

@ -967,26 +967,26 @@ class FunctionLikeNodeScanner
$duplicate_method_storage->has_visitor_issues = true;
return false;
} else {
// skip methods based on @since docblock tag
$doc_comment = $stmt->getDocComment();
}
if ($doc_comment) {
$docblock_info = null;
try {
$docblock_info = FunctionLikeDocblockParser::parse($doc_comment);
} catch (IncorrectDocblockException|DocblockParseException $e) {
}
if ($docblock_info) {
if ($docblock_info->since_php_major_version && !$this->aliases->namespace) {
if ($docblock_info->since_php_major_version > $this->codebase->php_major_version) {
return false;
}
if ($docblock_info->since_php_major_version === $this->codebase->php_major_version
&& $docblock_info->since_php_minor_version > $this->codebase->php_minor_version
) {
return false;
}
// skip methods based on @since docblock tag
$doc_comment = $stmt->getDocComment();
if ($doc_comment) {
$docblock_info = null;
try {
$docblock_info = FunctionLikeDocblockParser::parse($doc_comment);
} catch (IncorrectDocblockException|DocblockParseException $e) {
}
if ($docblock_info) {
if ($docblock_info->since_php_major_version && !$this->aliases->namespace) {
if ($docblock_info->since_php_major_version > $this->codebase->php_major_version) {
return false;
}
if ($docblock_info->since_php_major_version === $this->codebase->php_major_version
&& $docblock_info->since_php_minor_version > $this->codebase->php_minor_version
) {
return false;
}
}
}

View File

@ -429,7 +429,7 @@ class FileReferenceProvider
public function removeDeletedFilesFromReferences(): void
{
$deleted_files = self::getDeletedReferencedFiles();
$deleted_files = $this->getDeletedReferencedFiles();
if ($deleted_files) {
foreach ($deleted_files as $file) {

View File

@ -126,7 +126,7 @@ class NodeDataProvider implements \Psalm\NodeTypeProvider
public function isPureCompatible(PhpParser\Node\Expr $node) : bool
{
$node_type = self::getType($node);
$node_type = $this->getType($node);
return ($node_type && $node_type->reference_free) || isset($node->pure);
}

View File

@ -51,9 +51,10 @@ class ExplodeReturnTypeProvider implements \Psalm\Plugin\EventHandler\FunctionRe
? new Type\Atomic\TList($inner_type)
: new Type\Atomic\TNonEmptyList($inner_type)
]);
} elseif (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value))
&& $first_arg_type->hasString()
) {
}
if (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value))
&& $first_arg_type->hasString()) {
$can_be_false = true;
if ($first_arg_type->isString()) {
$can_be_false = false;

View File

@ -42,7 +42,9 @@ class GetObjectVarsReturnTypeProvider implements FunctionReturnTypeProviderInter
return new Type\Union([
new Type\Atomic\TKeyedArray($object_type->properties)
]);
} elseif ($object_type instanceof Type\Atomic\TNamedObject) {
}
if ($object_type instanceof Type\Atomic\TNamedObject) {
if (strtolower($object_type->value) === strtolower(stdClass::class)) {
return Type::parseString('array<string, mixed>');
}

View File

@ -1335,7 +1335,9 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
if ($existing_has_object && !$existing_has_string) {
return Type::parseString($assertion, null, $template_type_map);
} elseif ($existing_has_string && !$existing_has_object) {
}
if ($existing_has_string && !$existing_has_object) {
if (!$allow_string_comparison && $code_location) {
if (IssueBuffer::accepts(
new TypeDoesNotContainType(

View File

@ -53,14 +53,16 @@ class IntegerRangeComparator
if (isset($container_atomic_types['int'])) {
if (get_class($container_atomic_types['int']) === TInt::class) {
return true;
} elseif (get_class($container_atomic_types['int']) === TPositiveInt::class) {
}
if (get_class($container_atomic_types['int']) === TPositiveInt::class) {
if ($input_type_part->isPositive()) {
return true;
} else {
//every positive integer is satisfied by the positive-int int container so we reduce the range
$reduced_range->max_bound = 0;
unset($container_atomic_types['int']);
}
//every positive integer is satisfied by the positive-int int container so we reduce the range
$reduced_range->max_bound = 0;
unset($container_atomic_types['int']);
} else {
throw new \UnexpectedValueException('Should not happen: unknown int key');
}

View File

@ -99,7 +99,7 @@ class ObjectComparator
->getStorageFor($intersection_input_type->defining_class);
if ($codebase->classlikes->traitExists($container_class)
&& !\is_null($input_class_like)
&& $input_class_like !== null
&& isset(
$input_class_like->template_extended_params[$container_class][$container_param]
)) {

View File

@ -153,9 +153,13 @@ class NegatedAssertionReconciler extends Reconciler
}
return Type::getNull();
} elseif ($assertion === 'array-key-exists') {
}
if ($assertion === 'array-key-exists') {
return Type::getEmpty();
} elseif (substr($assertion, 0, 9) === 'in-array-') {
}
if (substr($assertion, 0, 9) === 'in-array-') {
$assertion = substr($assertion, 9);
$new_var_type = null;
try {
@ -189,7 +193,9 @@ class NegatedAssertionReconciler extends Reconciler
}
return $existing_var_type;
} elseif (substr($assertion, 0, 14) === 'has-array-key-') {
}
if (substr($assertion, 0, 14) === 'has-array-key-') {
return $existing_var_type;
}
}

View File

@ -435,6 +435,7 @@ class TypeParser
*/
public static function getComputedIntsFromMask(array $potential_ints) : array
{
/** @var list<int> */
$potential_values = [];
foreach ($potential_ints as $ith) {
@ -443,8 +444,8 @@ class TypeParser
$new_values[] = $ith;
if ($ith !== 0) {
for ($j = 0; $j < count($potential_values); $j++) {
$new_values[] = $ith | $potential_values[$j];
foreach ($potential_values as $potential_value) {
$new_values[] = $ith | $potential_value;
}
}

View File

@ -32,7 +32,9 @@ class CompactReport extends Report
foreach ($this->issues_data as $i => $issue_data) {
if (!$this->show_info && $issue_data->severity === Config::REPORT_INFO) {
continue;
} elseif ($current_file === null || $current_file !== $issue_data->file_name) {
}
if ($current_file === null || $current_file !== $issue_data->file_name) {
// If we're processing a new file, then wrap up the last table and render it out.
if ($buffer !== null) {
$table->render();

View File

@ -546,8 +546,10 @@ abstract class Type
Codebase $codebase
): ?Union {
$intersection_performed = false;
$type_1_mixed = $type_1->isMixed();
$type_2_mixed = $type_2->isMixed();
if ($type_1->isMixed() && $type_2->isMixed()) {
if ($type_1_mixed && $type_2_mixed) {
$combined_type = Type::getMixed();
} else {
$both_failed_reconciliation = false;
@ -562,10 +564,10 @@ abstract class Type
return $type_1;
}
if ($type_1->isMixed() && !$type_2->isMixed()) {
if ($type_1_mixed && !$type_2_mixed) {
$combined_type = clone $type_2;
$intersection_performed = true;
} elseif (!$type_1->isMixed() && $type_2->isMixed()) {
} elseif ($type_2_mixed) {
$combined_type = clone $type_1;
$intersection_performed = true;
} else {