Skip to content

Commit

Permalink
Allow specifying identifier to RuleError
Browse files Browse the repository at this point in the history
Ultimately every error in PHPStan should have its own unique identifier so that its
possible to group by error type and ignore errors based on identifier.

phpstan/phpstan#1686 (comment)
phpstan/phpstan#3065
  • Loading branch information
ruudk committed Dec 12, 2021
1 parent 5ad6d00 commit cbf3ff6
Show file tree
Hide file tree
Showing 18 changed files with 84 additions and 25 deletions.
3 changes: 2 additions & 1 deletion src/Calls/EchoCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Stmt\Echo_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -52,7 +53,7 @@ public function getNodeType(): string
/**
* @param Echo_ $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/EmptyCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Expr\Empty_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -52,7 +53,7 @@ public function getNodeType(): string
/**
* @param Empty_ $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/EvalCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Expr\Eval_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -52,7 +53,7 @@ public function getNodeType(): string
/**
* @param Eval_ $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/ExitDieCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Expr\Exit_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -52,7 +53,7 @@ public function getNodeType(): string
/**
* @param Exit_ $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/FunctionCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PhpParser\Node\Name;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -53,7 +54,7 @@ public function getNodeType(): string
/**
* @param FuncCall $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/MethodCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Broker\ClassNotFoundException;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -55,7 +56,7 @@ public function getNodeType(): string
/**
* @param MethodCall $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
* @throws ClassNotFoundException
*/
public function processNode(Node $node, Scope $scope): array
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/NewCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use PhpParser\Node\Name;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\ConstantScalarType;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
Expand Down Expand Up @@ -55,7 +56,7 @@ public function getNodeType(): string
/**
* @param New_ $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/PrintCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Expr\Print_;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -52,7 +53,7 @@ public function getNodeType(): string
/**
* @param Print_ $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/ShellExecCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\Expr\ShellExec;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -56,7 +57,7 @@ public function getNodeType(): string
/**
* @param ShellExec $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
*/
public function processNode(Node $node, Scope $scope): array
{
Expand Down
3 changes: 2 additions & 1 deletion src/Calls/StaticCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Broker\ClassNotFoundException;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\ShouldNotHappenException;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCall;
use Spaze\PHPStan\Rules\Disallowed\DisallowedCallFactory;
Expand Down Expand Up @@ -55,7 +56,7 @@ public function getNodeType(): string
/**
* @param StaticCall $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
* @throws ClassNotFoundException
*/
public function processNode(Node $node, Scope $scope): array
Expand Down
16 changes: 15 additions & 1 deletion src/DisallowedCall.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class DisallowedCall
/** @var array<int, DisallowedCallParam> */
private $allowExceptParams;

/** @var string|null */
private $identifier;


/**
* DisallowedCall constructor.
Expand All @@ -44,8 +47,9 @@ class DisallowedCall
* @param array<int, DisallowedCallParam> $allowParamsAnywhere
* @param array<int, DisallowedCallParam> $allowExceptParamsInAllowed
* @param array<int, DisallowedCallParam> $allowExceptParams
* @param string|null $identifier
*/
public function __construct(string $call, ?string $message, array $allowIn, array $allowInCalls, array $allowParamsInAllowed, array $allowParamsAnywhere, array $allowExceptParamsInAllowed, array $allowExceptParams)
public function __construct(string $call, ?string $message, array $allowIn, array $allowInCalls, array $allowParamsInAllowed, array $allowParamsAnywhere, array $allowExceptParamsInAllowed, array $allowExceptParams, ?string $identifier)
{
$this->call = $call;
$this->message = $message;
Expand All @@ -55,6 +59,7 @@ public function __construct(string $call, ?string $message, array $allowIn, arra
$this->allowParamsAnywhere = $allowParamsAnywhere;
$this->allowExceptParamsInAllowed = $allowExceptParamsInAllowed;
$this->allowExceptParams = $allowExceptParams;
$this->identifier = $identifier;
}


Expand Down Expand Up @@ -124,6 +129,15 @@ public function getAllowExceptParams(): array
}


/**
* @return string|null
*/
public function getIdentifier(): ?string
{
return $this->identifier;
}


public function getKey(): string
{
// The key consists of "initial" config values that would be overwritten with more specific details in a custom config.
Expand Down
16 changes: 15 additions & 1 deletion src/DisallowedConstant.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,24 @@ class DisallowedConstant
/** @var string[] */
private $allowIn;

/** @var string|null */
private $identifier;


/**
* DisallowedCall constructor.
*
* @param string $constant
* @param string|null $message
* @param string[] $allowIn
* @param string|null $identifier
*/
public function __construct(string $constant, ?string $message, array $allowIn)
public function __construct(string $constant, ?string $message, array $allowIn, ?string $identifier)
{
$this->constant = ltrim($constant, '\\');
$this->message = $message;
$this->allowIn = $allowIn;
$this->identifier = $identifier;
}


Expand All @@ -51,4 +56,13 @@ public function getAllowIn(): array
return $this->allowIn;
}


/**
* @return string|null
*/
public function getIdentifier(): string
{
return $this->identifier;
}

}
12 changes: 7 additions & 5 deletions src/DisallowedHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use PHPStan\Broker\ClassNotFoundException;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
Expand Down Expand Up @@ -111,19 +113,19 @@ private function getArgType(CallLike $node, Scope $scope, int $param): ?Type
* @param string|null $displayName
* @param DisallowedCall[] $disallowedCalls
* @param string|null $message
* @return string[]
* @return RuleError[]
*/
public function getDisallowedMessage(?CallLike $node, Scope $scope, string $name, ?string $displayName, array $disallowedCalls, ?string $message = null): array
{
foreach ($disallowedCalls as $disallowedCall) {
if ($this->callMatches($disallowedCall, $name) && !$this->isAllowed($scope, $node, $disallowedCall)) {
return [
sprintf(
RuleErrorBuilder::message(sprintf(
$message ?? 'Calling %s is forbidden, %s%s',
($displayName && $displayName !== $name) ? "{$name}() (as {$displayName}())" : "{$name}()",
$disallowedCall->getMessage(),
$disallowedCall->getCall() !== $name ? " [{$name}() matches {$disallowedCall->getCall()}()]" : ''
),
))->identifier($disallowedCall->getIdentifier())
];
}
}
Expand Down Expand Up @@ -222,12 +224,12 @@ public function getDisallowedConstantMessage(string $constant, Scope $scope, ?st
foreach ($disallowedConstants as $disallowedConstant) {
if ($disallowedConstant->getConstant() === $constant && !$this->isAllowedPath($scope, $disallowedConstant)) {
return [
sprintf(
RuleErrorBuilder::message(sprintf(
'Using %s%s is forbidden, %s',
$disallowedConstant->getConstant(),
$displayName && $displayName !== $disallowedConstant->getConstant() ? ' (as ' . $displayName . ')' : '',
$disallowedConstant->getMessage()
),
))->identifier($disallowedConstant->getIdentifier()),
];
}
}
Expand Down
16 changes: 15 additions & 1 deletion src/DisallowedNamespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@ class DisallowedNamespace
/** @var string[] */
private $allowIn;

/** @var string|null */
private $identifier;


/**
* @param string $namespace
* @param string|null $message
* @param string[] $allowIn
* @param string|null $identifier
*/
public function __construct(string $namespace, ?string $message, array $allowIn)
public function __construct(string $namespace, ?string $message, array $allowIn, ?string $identifier)
{
$this->namespace = ltrim($namespace, '\\');
$this->message = $message;
$this->allowIn = $allowIn;
$this->identifier = $identifier;
}


Expand All @@ -49,4 +54,13 @@ public function getAllowIn(): array
return $this->allowIn;
}


/**
* @return string|null
*/
public function getIdentifier(): string
{
return $this->identifier;
}

}
5 changes: 3 additions & 2 deletions src/DisallowedNamespaceHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Spaze\PHPStan\Rules\Disallowed;

use PHPStan\Analyser\Scope;
use PHPStan\Rules\RuleErrorBuilder;

class DisallowedNamespaceHelper
{
Expand Down Expand Up @@ -53,12 +54,12 @@ public function getDisallowedMessage(string $namespace, Scope $scope, array $dis
}

return [
sprintf(
RuleErrorBuilder::message(sprintf(
'Namespace %s is forbidden, %s%s',
$namespace,
$disallowedNamespace->getMessage(),
$disallowedNamespace->getNamespace() !== $namespace ? " [{$namespace} matches {$disallowedNamespace->getNamespace()}]" : ''
),
))->identifier($disallowedNamespace->getIdentifier()),
];
}

Expand Down
8 changes: 5 additions & 3 deletions src/Usages/ClassConstantUsages.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use PhpParser\Node\Identifier;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleError;
use PHPStan\Rules\RuleErrorBuilder;
use PHPStan\ShouldNotHappenException;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\TypeWithClassName;
Expand Down Expand Up @@ -54,7 +56,7 @@ public function getNodeType(): string
/**
* @param ClassConstFetch $node
* @param Scope $scope
* @return string[]
* @return RuleError[]
* @throws ShouldNotHappenException
*/
public function processNode(Node $node, Scope $scope): array
Expand All @@ -78,11 +80,11 @@ public function processNode(Node $node, Scope $scope): array
} else {
if ($usedOnType->hasConstant($constant)->no()) {
return [
sprintf(
RuleErrorBuilder::message(sprintf(
'Cannot access constant %s on %s',
$constant,
$usedOnType->describe(VerbosityLevel::getRecommendedLevelByType($usedOnType))
),
)),
];
} else {
$className = $usedOnType->getConstant($constant)->getDeclaringClass()->getDisplayName();
Expand Down
Loading

0 comments on commit cbf3ff6

Please sign in to comment.