Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite TryAnalyzer #7688

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADING.md
Expand Up @@ -836,3 +836,5 @@
- :information_source: migration possible using `Psalm\PluginFileExtensionsSocket`
- [BC] Method `\Psalm\Plugin\EventHandler\Event\AfterFunctionLikeAnalysisEvent::getClasslikeStorage()` was removed,
use correct `\Psalm\Plugin\EventHandler\Event\AfterFunctionLikeAnalysisEvent::getFunctionlikeStorage()` instead
- [BC] Property `Psalm\Context::$inside_try` was removed
- [BC] Property `Psalm\Context::$finally_scope` was removed
1 change: 1 addition & 0 deletions config.xsd
Expand Up @@ -399,6 +399,7 @@
<xs:element name="RawObjectIteration" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCast" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCastGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCatch" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantCondition" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantConditionGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
<xs:element name="RedundantFunctionCall" type="IssueHandlerType" minOccurs="0" />
Expand Down
1 change: 1 addition & 0 deletions docs/running_psalm/issues.md
Expand Up @@ -212,6 +212,7 @@
- [RawObjectIteration](issues/RawObjectIteration.md)
- [RedundantCast](issues/RedundantCast.md)
- [RedundantCastGivenDocblockType](issues/RedundantCastGivenDocblockType.md)
- [RedundantCatch](issues/RedundantCatch.md)
- [RedundantCondition](issues/RedundantCondition.md)
- [RedundantConditionGivenDocblockType](issues/RedundantConditionGivenDocblockType.md)
- [RedundantFunctionCall](issues/RedundantFunctionCall.md)
Expand Down
23 changes: 23 additions & 0 deletions docs/running_psalm/issues/RedundantCatch.md
@@ -0,0 +1,23 @@
# RedundantCatch

Emitted when catching an exception that was already caught.

```php
<?php

class A {}
try {
$worked = true;
} catch (Throwable $e) {
} catch (Exception $e) {
}
```

```php
<?php

try {
$worked = true;
} catch (Exception|Throwable $e) {
}
```
4 changes: 2 additions & 2 deletions examples/plugins/FunctionCasingChecker.php
Expand Up @@ -58,7 +58,7 @@ public static function afterMethodCallAnalysis(AfterMethodCallAnalysisEvent $eve
// fall through
}
}
} catch (Exception $e) {
} catch (Exception $_) {
// can throw if storage is missing
}
}
Expand Down Expand Up @@ -98,7 +98,7 @@ public static function afterFunctionCallAnalysis(AfterFunctionCallAnalysisEvent
// fall through
}
}
} catch (Exception $e) {
} catch (Exception $_) {
// can throw if storage is missing
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/Psalm/Codebase.php
Expand Up @@ -946,7 +946,7 @@ public function invalidateInformationForFile(string $file_path): void

try {
$file_storage = $this->file_storage_provider->get($file_path);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
return;
}

Expand Down Expand Up @@ -1086,7 +1086,7 @@ public function getSymbolInformation(string $file_path, string $symbol): ?array
'type' => '<?php ' . ($storage->abstract ? 'abstract ' : '') . 'class ' . $storage->name,
'description' => $storage->description,
];
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
}

if (strpos($symbol, '\\')) {
Expand Down Expand Up @@ -1198,7 +1198,7 @@ public function getSymbolLocation(string $file_path, string $symbol): ?CodeLocat
error_log($e->getMessage());

return null;
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
return null;
}
}
Expand Down Expand Up @@ -1348,7 +1348,7 @@ public function getSignatureInformation(
$params = $function_storage->params;
$signature_label = $function_storage->cased_name;
$signature_documentation = $function_storage->description;
} catch (Exception $exception) {
} catch (Exception $_) {
if (InternalCallMapHandler::inCallMap($function_symbol)) {
$callables = InternalCallMapHandler::getCallablesFromCallMap($function_symbol);

Expand Down Expand Up @@ -1608,7 +1608,7 @@ public function getCompletionItemsForPartialSymbol(
foreach ($file_storage->classlikes_in_file as $fq_class_name => $_) {
try {
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
} catch (Exception $e) {
} catch (Exception $_) {
continue;
}

Expand Down Expand Up @@ -1683,7 +1683,7 @@ public function getCompletionItemsForPartialSymbol(
try {
$class_storage = $this->classlike_storage_provider->get($fq_class_name);
$description = $class_storage->description;
} catch (Exception $e) {
} catch (Exception $_) {
$description = null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Config.php
Expand Up @@ -1643,7 +1643,7 @@ public function reportIssueInFile(string $issue_type, string $file_path): bool
try {
$file_storage = $codebase->file_storage_provider->get($file_path);
$dependent_files += $file_storage->required_by_file_paths;
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
// do nothing
}
}
Expand Down Expand Up @@ -2406,7 +2406,7 @@ public function getPHPVersionFromComposerJson(): ?string
if (file_exists($composer_json_path)) {
try {
$composer_json = json_decode(file_get_contents($composer_json_path), true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
} catch (JsonException $_) {
$composer_json = null;
}

Expand Down
30 changes: 20 additions & 10 deletions src/Psalm/Context.php
Expand Up @@ -6,8 +6,8 @@
use Psalm\Internal\Clause;
use Psalm\Internal\ReferenceConstraint;
use Psalm\Internal\Scope\CaseScope;
use Psalm\Internal\Scope\FinallyScope;
use Psalm\Internal\Scope\LoopScope;
use Psalm\Internal\Scope\TryCatchScope;
use Psalm\Internal\Type\AssertionReconciler;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Type\Atomic\DependentType;
Expand Down Expand Up @@ -155,13 +155,6 @@ final class Context
*/
public $inside_assignment = false;

/**
* Whether or not we're inside a try block.
*
* @var bool
*/
public $inside_try = false;

/**
* @var null|CodeLocation
*/
Expand Down Expand Up @@ -349,9 +342,9 @@ final class Context
public $case_scope;

/**
* @var FinallyScope|null
* @var TryCatchScope|null
*/
public $finally_scope;
public $try_catch_scope = null;

/**
* @var Context|null
Expand Down Expand Up @@ -442,6 +435,23 @@ public function __clone()
}
}

/**
* $vars_in_scope isn't normally cloned, but sometimes this is needed.
*/
public function cloneVarsInScope(): void
{
// New array is required: https://3v4l.org/ggfb9 https://3v4l.org/EfsTZ
// References are weird...
$old_vars_in_scope = $this->vars_in_scope;
$this->vars_in_scope = [];
foreach ($old_vars_in_scope as $var_id => $var_type) {
$this->vars_in_scope[$var_id] = clone $var_type;
}
foreach ($this->references_in_scope as $reference_id => $referenced_id) {
$this->vars_in_scope[$reference_id] = &$this->vars_in_scope[$referenced_id];
}
}
weirdan marked this conversation as resolved.
Show resolved Hide resolved

/**
* Updates the parent context, looking at the changes within a block and then applying those changes, where
* necessary, to the parent context
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php
Expand Up @@ -43,7 +43,7 @@ public static function checkForParadox(
): void {
try {
$negated_formula2 = Algebra::negateFormula($formula_2);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
return;
}

Expand Down
10 changes: 5 additions & 5 deletions src/Psalm/Internal/Analyzer/ClassAnalyzer.php
Expand Up @@ -562,7 +562,7 @@ public function analyze(

try {
$trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name);
} catch (Exception $e) {
} catch (Exception $_) {
continue;
}

Expand Down Expand Up @@ -910,7 +910,7 @@ public static function addContextProperties(
try {
$docBlock = DocComment::parsePreservingLength($docComment);
$suppressed = $docBlock->tags['psalm-suppress'] ?? [];
} catch (DocblockParseException $e) {
} catch (DocblockParseException $_) {
// do nothing to keep original behavior
}
}
Expand Down Expand Up @@ -2036,7 +2036,7 @@ private function checkImplementedInterfaces(

try {
$interface_storage = $classlike_storage_provider->get($fq_interface_name);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
return false;
}

Expand Down Expand Up @@ -2070,7 +2070,7 @@ private function checkImplementedInterfaces(
foreach ($storage->class_implements as $fq_interface_name_lc => $fq_interface_name) {
try {
$interface_storage = $classlike_storage_provider->get($fq_interface_name_lc);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
return false;
}

Expand Down Expand Up @@ -2391,7 +2391,7 @@ private function checkParentClass(
$code_location,
$storage->template_type_extends_count[$parent_fq_class_name] ?? 0
);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
// do nothing
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php
Expand Up @@ -818,7 +818,7 @@ public static function getClassesForFile(Codebase $codebase, string $file_path):
{
try {
return $codebase->file_storage_provider->get($file_path)->classlikes_in_file;
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
return [];
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Psalm/Internal/Analyzer/CommentAnalyzer.php
Expand Up @@ -131,7 +131,7 @@ public static function arrayToDocblocks(
$template_type_map,
$type_aliases
);
} catch (TypeParseTreeException $e) {
} catch (TypeParseTreeException $_) {
throw new DocblockParseException($line_parts[0] . ' is not a valid type');
}

Expand Down Expand Up @@ -161,7 +161,7 @@ public static function arrayToDocblocks(
$template_type_map ?: [],
$type_aliases ?: []
);
} catch (TypeParseTreeException $e) {
} catch (TypeParseTreeException $_) {
throw new DocblockParseException(
$line_parts[0] .
' is not a valid type' .
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/FileAnalyzer.php
Expand Up @@ -173,7 +173,7 @@ public function analyze(

try {
$stmts = $codebase->getStatementsForFile($this->file_path);
} catch (PhpParser\Error $e) {
} catch (PhpParser\Error $_) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php
Expand Up @@ -1597,7 +1597,7 @@ public function getFunctionLikeStorage(?StatementsAnalyzer $statements_analyzer

try {
return $codebase_methods->getStorage($method_id);
} catch (UnexpectedValueException $e) {
} catch (UnexpectedValueException $_) {
$declaring_method_id = $codebase_methods->getDeclaringMethodId($method_id);

if ($declaring_method_id === null) {
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php
Expand Up @@ -70,7 +70,7 @@ public function analyze(): void

try {
$extended_interface_storage = $codebase->classlike_storage_provider->get($extended_interface_name);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $_) {
continue;
}

Expand Down
Expand Up @@ -71,7 +71,7 @@ public static function analyze(
$cond_referenced_var_ids = $if_conditional_scope->cond_referenced_var_ids;
$assigned_in_conditional_var_ids = $if_conditional_scope->assigned_in_conditional_var_ids;
$entry_clauses = $if_conditional_scope->entry_clauses;
} catch (ScopeAnalysisException $e) {
} catch (ScopeAnalysisException $_) {
return false;
}

Expand Down Expand Up @@ -194,7 +194,7 @@ function (Clause $c) use ($assigned_in_conditional_var_ids, $elseif_cond_id): Cl
$negated_elseif_types = Algebra::getTruthsFromFormula(
Algebra::negateFormula($elseif_clauses)
);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
$reconcilable_elseif_types = [];
$negated_elseif_types = [];
}
Expand Down Expand Up @@ -432,7 +432,7 @@ function (Clause $c) use ($assigned_in_conditional_var_ids, $elseif_cond_id): Cl
Algebra::negateFormula($elseif_clauses)
)
);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
$if_scope->negated_clauses = [];
}

Expand Down
Expand Up @@ -112,7 +112,7 @@ public static function analyze(
// this is the context for stuff that happens after the `if` block
$post_if_context = $if_conditional_scope->post_if_context;
$assigned_in_conditional_var_ids = $if_conditional_scope->assigned_in_conditional_var_ids;
} catch (ScopeAnalysisException $e) {
} catch (ScopeAnalysisException $_) {
return false;
}

Expand Down Expand Up @@ -204,7 +204,7 @@ function (Clause $c) use ($mixed_var_ids, $cond_object_id): Clause {

try {
$if_scope->negated_clauses = Algebra::negateFormula($if_clauses);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
try {
$if_scope->negated_clauses = FormulaGenerator::getFormula(
$cond_object_id,
Expand All @@ -215,7 +215,7 @@ function (Clause $c) use ($mixed_var_ids, $cond_object_id): Clause {
$codebase,
false
);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
$if_scope->negated_clauses = [];
}
}
Expand Down
Expand Up @@ -465,7 +465,7 @@ public static function analyze(

try {
$negated_pre_condition_clauses = Algebra::negateFormula(array_merge(...$pre_condition_clauses));
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
$negated_pre_condition_clauses = [];
}

Expand Down
Expand Up @@ -439,7 +439,7 @@ public static function analyze(
if ($case_clauses && $case_equality_expr) {
try {
$negated_case_clauses = Algebra::negateFormula($case_clauses);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
$case_equality_expr_id = spl_object_id($case_equality_expr);

try {
Expand All @@ -453,7 +453,7 @@ public static function analyze(
false,
false
);
} catch (ComplicatedExpressionException $e) {
} catch (ComplicatedExpressionException $_) {
$negated_case_clauses = [];
}
}
Expand Down