Skip to content

Commit

Permalink
Merge pull request #138 from boesing/qa/normalize-code-issues
Browse files Browse the repository at this point in the history
This normalizes the code issue generation
  • Loading branch information
boesing authored Dec 1, 2022
2 parents 0fa20db + 31cc373 commit eb13aa3
Show file tree
Hide file tree
Showing 13 changed files with 95 additions and 54 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "BSD-3-Clause",
"require": {
"php": "^7.4 || ~8.0.0 || ~8.1.0",
"vimeo/psalm": "^4.23 || ^5.0",
"vimeo/psalm": "^4.30 || ^5.0",
"webmozart/assert": "^1.10"
},
"require-dev": {
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,15 @@
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
findUnusedPsalmSuppress="true"
ensureArrayStringOffsetsExist="true"
ensureArrayIntOffsetsExist="true"
ignoreInternalFunctionFalseReturn="false"
ignoreInternalFunctionNullReturn="false"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<RedundantCondition>
<!-- Lets keep these issues as info-level until we remove support for psalm v4 -->
<errorLevel type="info">
<directory name="src"/>
</errorLevel>
</RedundantCondition>
</issueHandlers>
</psalm>
10 changes: 5 additions & 5 deletions src/EventHandler/FunctionArgumentValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
use Boesing\PsalmPluginStringf\ArgumentValidator\ArgumentValidator;
use Boesing\PsalmPluginStringf\Parser\Psalm\PhpVersion;
use Boesing\PsalmPluginStringf\Parser\TemplatedStringParser\TemplatedStringParser;
use Boesing\PsalmPluginStringf\Psalm\Issue\TooFewArguments;
use Boesing\PsalmPluginStringf\Psalm\Issue\TooManyArguments;
use InvalidArgumentException;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\VariadicPlaceholder;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Issue\ArgumentIssue;
use Psalm\Issue\TooFewArguments;
use Psalm\Issue\TooManyArguments;
use Psalm\Issue\PluginIssue;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\AfterEveryFunctionCallAnalysisInterface;
use Psalm\Plugin\EventHandler\Event\AfterEveryFunctionCallAnalysisEvent;
Expand Down Expand Up @@ -62,7 +62,7 @@ private function createCodeIssue(
string $functionName,
int $argumentCount,
int $requiredArgumentCount
): ArgumentIssue {
): PluginIssue {
$message = $this->createIssueMessage(
$functionName,
$requiredArgumentCount,
Expand Down Expand Up @@ -171,7 +171,7 @@ private function validate(
return;
}

IssueBuffer::add($this->createCodeIssue(
IssueBuffer::maybeAdd($this->createCodeIssue(
$this->codeLocation,
$functionName,
$validationResult->actualArgumentCount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

use Boesing\PsalmPluginStringf\Parser\Psalm\PhpVersion;
use Boesing\PsalmPluginStringf\Parser\TemplatedStringParser\TemplatedStringParser;
use Boesing\PsalmPluginStringf\Psalm\Issue\PossiblyInvalidArgument;
use InvalidArgumentException;
use PhpParser\Node\Arg;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Issue\PossiblyInvalidArgument;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\AfterEveryFunctionCallAnalysisInterface;
use Psalm\Plugin\EventHandler\Event\AfterEveryFunctionCallAnalysisEvent;
Expand Down Expand Up @@ -141,7 +141,7 @@ private function assertArgumentsMatchingPlaceholderTypes(
continue;
}

IssueBuffer::add(
IssueBuffer::maybeAdd(
new PossiblyInvalidArgument(
sprintf(
'Argument %d inferred as "%s" does not match (any of) the suggested type(s) "%s"',
Expand Down Expand Up @@ -206,6 +206,8 @@ private function invalidTypeWouldBeCoveredByPsalmItself(Atomic $type): bool
}

/**
* @see \Boesing\PsalmPluginStringf\Plugin::registerFeatureHook()
*
* @param array<non-empty-string,string> $options
*/
public static function applyOptions(array $options): void
Expand Down
2 changes: 1 addition & 1 deletion src/EventHandler/UnnecessaryFunctionCallValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,6 @@ private function assertFunctionCallMakesSense(
}

// TODO: find out how to provide psalter functionality
IssueBuffer::add(new UnnecessaryFunctionCall($codeLocation, $this->functionName), false);
IssueBuffer::maybeAdd(new UnnecessaryFunctionCall($codeLocation, $this->functionName));
}
}
1 change: 1 addition & 0 deletions src/Parser/TemplatedStringParser/TemplatedStringParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ static function (
$templateWithoutPlaceholders = $template;

foreach ($placeholders as $placeholder) {
assert(isset($placeholder[0]));
[$placeholderValue, $placeholderIndex] = $placeholder[0];
$placeholderLength = strlen($placeholderValue);
$templateWithoutPlaceholders = substr_replace(
Expand Down
2 changes: 0 additions & 2 deletions src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ private function registerExperimentalHooks(RegistrationInterface $registration,
}

foreach ($config->experimental->children() as $element) {
assert($element instanceof SimpleXMLElement);
$name = $element->getName();
if (! isset(self::EXPERIMENTAL_FEATURES[$name])) {
continue;
Expand Down Expand Up @@ -93,7 +92,6 @@ private function extractOptionsFromElement(SimpleXMLElement $element): array
$options = [];

foreach ($element->attributes() ?? [] as $attribute) {
assert($attribute instanceof SimpleXMLElement);
$name = $attribute->getName();
assert($name !== '');

Expand Down
24 changes: 24 additions & 0 deletions src/Psalm/Issue/PossiblyInvalidArgument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Boesing\PsalmPluginStringf\Psalm\Issue;

use Psalm\CodeLocation;
use Psalm\Issue\PluginIssue;

use function strtolower;

final class PossiblyInvalidArgument extends PluginIssue
{
public ?string $function_id;

public function __construct(
string $message,
CodeLocation $code_location,
?string $function_id = null
) {
parent::__construct($message, $code_location);
$this->function_id = $function_id ? strtolower($function_id) : null;
}
}
24 changes: 24 additions & 0 deletions src/Psalm/Issue/TooFewArguments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Boesing\PsalmPluginStringf\Psalm\Issue;

use Psalm\CodeLocation;
use Psalm\Issue\PluginIssue;

use function strtolower;

final class TooFewArguments extends PluginIssue
{
public ?string $function_id;

public function __construct(
string $message,
CodeLocation $code_location,
?string $function_id = null
) {
parent::__construct($message, $code_location);
$this->function_id = $function_id ? strtolower($function_id) : null;
}
}
24 changes: 24 additions & 0 deletions src/Psalm/Issue/TooManyArguments.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Boesing\PsalmPluginStringf\Psalm\Issue;

use Psalm\CodeLocation;
use Psalm\Issue\PluginIssue;

use function strtolower;

final class TooManyArguments extends PluginIssue
{
public ?string $function_id;

public function __construct(
string $message,
CodeLocation $code_location,
?string $function_id = null
) {
parent::__construct($message, $code_location);
$this->function_id = $function_id ? strtolower($function_id) : null;
}
}
9 changes: 6 additions & 3 deletions src/Psalm/Issue/UnnecessaryFunctionCall.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
namespace Boesing\PsalmPluginStringf\Psalm\Issue;

use Psalm\CodeLocation;
use Psalm\Issue\FunctionIssue;
use Psalm\Issue\PluginIssue;

final class UnnecessaryFunctionCall extends FunctionIssue
final class UnnecessaryFunctionCall extends PluginIssue
{
public string $function_id;

public function __construct(CodeLocation $code_location, string $function_id)
{
parent::__construct(
'Function call is unnecessary as there is no placeholder within the template.',
$code_location,
$function_id,
);

$this->function_id = $function_id;
}
}
31 changes: 0 additions & 31 deletions tests/acceptance/SprintfNonEmptyString.feature
Original file line number Diff line number Diff line change
Expand Up @@ -173,28 +173,13 @@ Feature: non empty template passed to sprintf results in non-empty-string
When I run Psalm
Then I see no errors

Scenario: template is empty and value which is passed to the string is boolean (false) on psalm v4-
Given I have the following code
"""
/** @psalm-suppress InvalidArgument Ignore the fact that we are passing `false` to sprintf for testing purposes */
$string = sprintf('%s', false);
nonEmptyString($string);
"""
And I have Psalm older than "5.0" because of "older psalm versions do not have `but` in the error message."
When I run Psalm
Then I see these errors
| Type | Message |
| ArgumentTypeCoercion | Argument 1 of nonEmptyString expects non-empty-string, parent type string provided |
And I see no other errors

Scenario: template is empty and value which is passed to the string is boolean (false) on psalm v5+
Given I have the following code
"""
/** @psalm-suppress InvalidArgument Ignore the fact that we are passing `false` to sprintf for testing purposes */
$string = sprintf('%s', false);
nonEmptyString($string);
"""
And I have Psalm newer than "4.99" because of "newer psalm versions do have `but` in the error message."
When I run Psalm
Then I see these errors
| Type | Message |
Expand All @@ -212,21 +197,6 @@ Feature: non empty template passed to sprintf results in non-empty-string
When I run psalm
Then I see no errors

Scenario: template gets passed float argument without knowing its value on psalm v4+
Given I have the following code
"""
/** @psalm-var float $float */
$float = 0.00;
$string = sprintf('%0.2f', $float);
nonEmptyString($string);
"""
And I have Psalm older than "5.0" because of "older psalm versions do not have `but` in the error message."
When I run psalm
Then I see these errors
| Type | Message |
| ArgumentTypeCoercion | Argument 1 of nonEmptyString expects non-empty-string, parent type string provided |
And I see no other errors

Scenario: template gets passed float argument without knowing its value on psalm v5+
Given I have the following code
"""
Expand All @@ -235,7 +205,6 @@ Feature: non empty template passed to sprintf results in non-empty-string
$string = sprintf('%0.2f', $float);
nonEmptyString($string);
"""
And I have Psalm newer than "4.99" because of "newer psalm versions do have `but` in the error message."
When I run psalm
Then I see these errors
| Type | Message |
Expand Down

0 comments on commit eb13aa3

Please sign in to comment.