mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Add extra issue for invalid clone and fix issue reporting;
This commit is contained in:
parent
4b283564ca
commit
e3a9cb98c3
@ -85,6 +85,7 @@
|
||||
<xs:element name="InvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="InvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="InvalidClass" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="InvalidClone" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="InvalidParamDefault" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="InvalidDocblock" type="IssueHandlerType" minOccurs="0" />
|
||||
<xs:element name="InvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
|
||||
|
@ -472,7 +472,7 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc
|
||||
$global_context ? clone $global_context : null
|
||||
);
|
||||
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $source->getFileName())) {
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $source->getFilePath())) {
|
||||
$return_type_location = null;
|
||||
$secondary_return_type_location = null;
|
||||
|
||||
|
@ -307,7 +307,7 @@ class FileChecker extends SourceChecker implements StatementsSource
|
||||
$function_context = new Context($this->file_name, $this->context->self);
|
||||
$function_checker->analyze($function_context, $this->context);
|
||||
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $this->file_name)) {
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $this->file_path)) {
|
||||
/** @var string */
|
||||
$method_id = $function_checker->getMethodId();
|
||||
|
||||
|
@ -955,11 +955,11 @@ class CallChecker
|
||||
if ($function_params !== null) {
|
||||
$by_ref = $argument_offset < count($function_params)
|
||||
? $function_params[$argument_offset]->by_ref
|
||||
: $last_param->is_variadic && $last_param->by_ref;
|
||||
: $last_param && $last_param->is_variadic && $last_param->by_ref;
|
||||
|
||||
$by_ref_type = null;
|
||||
|
||||
if ($by_ref) {
|
||||
if ($by_ref && $last_param) {
|
||||
$by_ref_type = $argument_offset < count($function_params)
|
||||
? clone $function_params[$argument_offset]->type
|
||||
: clone $last_param->type;
|
||||
@ -992,11 +992,11 @@ class CallChecker
|
||||
if ($function_params !== null) {
|
||||
$by_ref = $argument_offset < count($function_params)
|
||||
? $function_params[$argument_offset]->by_ref
|
||||
: $last_param->is_variadic && $last_param->by_ref;
|
||||
: $last_param && $last_param->is_variadic && $last_param->by_ref;
|
||||
|
||||
$by_ref_type = null;
|
||||
|
||||
if ($by_ref) {
|
||||
if ($by_ref && $last_param) {
|
||||
$by_ref_type = $argument_offset < count($function_params)
|
||||
? clone $function_params[$argument_offset]->type
|
||||
: clone $last_param->type;
|
||||
|
@ -17,6 +17,7 @@ use Psalm\CodeLocation;
|
||||
use Psalm\Config;
|
||||
use Psalm\Context;
|
||||
use Psalm\Issue\ForbiddenCode;
|
||||
use Psalm\Issue\InvalidClone;
|
||||
use Psalm\Issue\InvalidOperand;
|
||||
use Psalm\Issue\InvalidScope;
|
||||
use Psalm\Issue\InvalidStaticVariable;
|
||||
@ -305,13 +306,7 @@ class ExpressionChecker
|
||||
|
||||
$stmt->inferredType = Type::getNull();
|
||||
} elseif ($stmt instanceof PhpParser\Node\Expr\Clone_) {
|
||||
if (self::analyze($statements_checker, $stmt->expr, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (property_exists($stmt->expr, 'inferredType')) {
|
||||
$stmt->inferredType = $stmt->expr->inferredType;
|
||||
}
|
||||
self::analyzeClone($statements_checker, $stmt, $context);
|
||||
} elseif ($stmt instanceof PhpParser\Node\Expr\Instanceof_) {
|
||||
if (self::analyze($statements_checker, $stmt->expr, $context) === false) {
|
||||
return false;
|
||||
@ -1686,6 +1681,42 @@ class ExpressionChecker
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StatementsChecker $statements_checker
|
||||
* @param PhpParser\Node\Expr\Clone_ $stmt
|
||||
* @param Context $context
|
||||
* @return false|null
|
||||
*/
|
||||
protected static function analyzeClone(
|
||||
StatementsChecker $statements_checker,
|
||||
PhpParser\Node\Expr\Clone_ $stmt,
|
||||
Context $context
|
||||
) {
|
||||
if (self::analyze($statements_checker, $stmt->expr, $context) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($stmt->expr->inferredType)) {
|
||||
foreach ($stmt->expr->inferredType->types as $clone_type_part) {
|
||||
if (!$clone_type_part instanceof TNamedObject && !$clone_type_part instanceof TObject) {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidClone(
|
||||
'Cannot clone ' . $clone_type_part,
|
||||
new CodeLocation($statements_checker->getSource(), $stmt)
|
||||
),
|
||||
$statements_checker->getSuppressedIssues()
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->inferredType = $stmt->expr->inferredType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fq_class_name
|
||||
* @return boolean
|
||||
|
@ -186,7 +186,7 @@ class StatementsChecker extends SourceChecker implements StatementsSource
|
||||
|
||||
$config = Config::getInstance();
|
||||
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $this->getFileName())) {
|
||||
if (!$config->excludeIssueInFile('InvalidReturnType', $this->getFilePath())) {
|
||||
/** @var string */
|
||||
$method_id = $function_checkers[$stmt->name]->getMethodId();
|
||||
|
||||
|
@ -422,24 +422,22 @@ class Config
|
||||
|
||||
/**
|
||||
* @param string $issue_type
|
||||
* @param string $file_name
|
||||
* @param string $file_path
|
||||
* @return bool
|
||||
*/
|
||||
public function excludeIssueInFile($issue_type, $file_name)
|
||||
public function excludeIssueInFile($issue_type, $file_path)
|
||||
{
|
||||
if (!$this->totally_typed && in_array($issue_type, self::$MIXED_ISSUES)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$file_name = $this->shortenFileName($file_name);
|
||||
|
||||
if ($this->project_files && $this->hide_external_errors) {
|
||||
if (!$this->isInProjectDirs($file_name)) {
|
||||
if (!$this->isInProjectDirs($file_path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->getReportingLevelForFile($issue_type, $file_name) === self::REPORT_SUPPRESS) {
|
||||
if ($this->getReportingLevelForFile($issue_type, $file_path) === self::REPORT_SUPPRESS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -452,18 +450,21 @@ class Config
|
||||
*/
|
||||
public function isInProjectDirs($file_path)
|
||||
{
|
||||
if ($file_path[0] !== '/') {
|
||||
throw new \UnexpectedValueException('eesh');
|
||||
}
|
||||
return $this->project_files && $this->project_files->allows($file_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $issue_type
|
||||
* @param string $file_name
|
||||
* @param string $file_path
|
||||
* @return string
|
||||
*/
|
||||
public function getReportingLevelForFile($issue_type, $file_name)
|
||||
public function getReportingLevelForFile($issue_type, $file_path)
|
||||
{
|
||||
if (isset($this->issue_handlers[$issue_type])) {
|
||||
return $this->issue_handlers[$issue_type]->getReportingLevelForFile($file_name);
|
||||
return $this->issue_handlers[$issue_type]->getReportingLevelForFile($file_path);
|
||||
}
|
||||
|
||||
return self::REPORT_ERROR;
|
||||
|
@ -13,6 +13,7 @@ class ErrorLevelFileFilter extends FileFilter
|
||||
|
||||
/**
|
||||
* @param SimpleXMLElement $e
|
||||
* @param Config $config
|
||||
* @param bool $inclusive
|
||||
* @return self
|
||||
*/
|
||||
|
@ -55,13 +55,13 @@ class IssueHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file_name
|
||||
* @param string $file_path
|
||||
* @return string
|
||||
*/
|
||||
public function getReportingLevelForFile($file_name)
|
||||
public function getReportingLevelForFile($file_path)
|
||||
{
|
||||
foreach ($this->custom_levels as $custom_level) {
|
||||
if ($custom_level->allows($file_name)) {
|
||||
if ($custom_level->allows($file_path)) {
|
||||
return $custom_level->getErrorLevel();
|
||||
}
|
||||
}
|
||||
|
6
src/Psalm/Issue/InvalidClone.php
Normal file
6
src/Psalm/Issue/InvalidClone.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Psalm\Issue;
|
||||
|
||||
class InvalidClone extends CodeError
|
||||
{
|
||||
}
|
@ -41,7 +41,7 @@ class IssueBuffer
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($config->excludeIssueInFile($issue_type, $e->getFileName())) {
|
||||
if ($config->excludeIssueInFile($issue_type, $e->getFilePath())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user