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

disussion#7862: adds first test case #7890

Draft
wants to merge 50 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
6cf7b26
disussion#7862: adds first test case
BruceGitHub Apr 23, 2022
d0f4311
adds pretty options
BruceGitHub May 11, 2022
e84df65
fix test
BruceGitHub May 11, 2022
3c204d5
adds helper classes
BruceGitHub May 11, 2022
4baa288
changes ConsoleReport.php to use pretty option
BruceGitHub May 11, 2022
10e4fba
fix code style
BruceGitHub May 11, 2022
6c88ff9
disussion#7862: adds first test case
BruceGitHub Apr 23, 2022
5882b16
adds pretty options
BruceGitHub May 11, 2022
38e63e0
fix test
BruceGitHub May 11, 2022
4fd6c8a
adds helper classes
BruceGitHub May 11, 2022
749d437
changes ConsoleReport.php to use pretty option
BruceGitHub May 11, 2022
d398f05
fix code style
BruceGitHub May 11, 2022
4f91c39
spyke commit use InvolvedTypes.php
BruceGitHub May 17, 2022
7226ac8
Merge remote-tracking branch 'origin/pr-prettry-print-from-discussion…
BruceGitHub May 17, 2022
7f181e2
simplify the code
BruceGitHub May 17, 2022
3fe68d2
cs-fix
BruceGitHub May 18, 2022
c28eab1
changes namespace of InvolvedTypes.php, fixes some test
BruceGitHub May 18, 2022
f41279b
fixes typo
BruceGitHub May 19, 2022
e2a6c50
cs-fix
BruceGitHub May 19, 2022
9ab3e42
try to fix issue with windows
BruceGitHub May 19, 2022
4949c77
fix test ReportOutputTest.php
BruceGitHub May 19, 2022
0a4ade0
try to fix psalm issues
BruceGitHub May 19, 2022
b8843d6
supress psalm error for probable error
BruceGitHub May 19, 2022
48f77df
suppress psalm error in test
BruceGitHub May 19, 2022
454753a
adds test InvolvedTypesTest.php
BruceGitHub May 23, 2022
029a06f
refactor PrettyFormat.php
BruceGitHub May 23, 2022
b0ff81a
change name PrettyGeneric.php to PrettyHelper.php
BruceGitHub May 23, 2022
7883ece
Merge branch 'master' into pr-prettry-print-from-discussion-7862
BruceGitHub May 23, 2022
1e45d5e
adds test for PrettyCompareTest.php
BruceGitHub May 27, 2022
8008f8f
adds test for PrettyFormatTest.php
BruceGitHub May 27, 2022
74db30e
adds test for PrettyCursorBracketTest.php
BruceGitHub May 27, 2022
9f46f65
adds test for PrettyCompareTest.php
BruceGitHub May 27, 2022
ecd78ab
try to fix windows issues
BruceGitHub May 28, 2022
187584b
Merge branch 'master' into pr-prettry-print-from-discussion-7862
BruceGitHub May 28, 2022
6472936
try to fix windows issues attempt 1
BruceGitHub May 28, 2022
0160796
try to fix windows issues attempt 1 + csfix
BruceGitHub May 28, 2022
62b57b6
try to fix windows issues attempt 2
BruceGitHub May 28, 2022
257a69d
Merge branch 'master' into pr-prettry-print-from-discussion-7862
BruceGitHub May 30, 2022
5b41392
try to fix windows issues attempt 3
BruceGitHub May 30, 2022
76ede51
try to fix windows issues attempt 4 (double quote)
BruceGitHub Jun 2, 2022
fdd3f32
try to fix windows issues attempt 5 (mark test as skipped)
BruceGitHub Jun 2, 2022
e151de1
try to fix windows issues attempt 6 (normalized to \n)
BruceGitHub Jun 2, 2022
f42aee2
try to fix windows issues attempt 6-a (enable some test \n)
BruceGitHub Jun 2, 2022
3a25e06
try to fix windows issues attempt 6-b (add compare test \n)
BruceGitHub Jun 2, 2022
ba18b91
try to fix windows issues attempt 6-c (add format test \n)
BruceGitHub Jun 2, 2022
935806f
optimize common code with trait
BruceGitHub Jun 2, 2022
155c6d0
Revert "optimize common code with trait"
BruceGitHub Jun 3, 2022
e322eef
new testcase and micro fix
BruceGitHub Jun 10, 2022
1483b93
improve code and test of prettyFormat
BruceGitHub Jun 10, 2022
8bac4c6
improvement code, and test of prettyMatchToken
BruceGitHub Jun 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/Psalm/Internal/Analyzer/IssueData.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Psalm\Internal\Analyzer;

use Psalm\InvolvedTypes;

use function str_pad;

use const STR_PAD_LEFT;
Expand Down Expand Up @@ -127,6 +129,12 @@ class IssueData
*/
public $dupe_key;

/**
* @var ?InvolvedTypes
* @readonly
*/
public $involvedTypes;

/**
* @param ?list<DataFlowNodeData|array{label: string, entry_path_type: string}> $taint_trace
* @param ?list<DataFlowNodeData> $other_references
Expand All @@ -151,7 +159,8 @@ public function __construct(
int $error_level = -1,
?array $taint_trace = null,
array $other_references = null,
?string $dupe_key = null
?string $dupe_key = null,
?InvolvedTypes $involvedTypes = null
) {
$this->severity = $severity;
$this->line_from = $line_from;
Expand All @@ -174,5 +183,6 @@ public function __construct(
$this->taint_trace = $taint_trace;
$this->other_references = $other_references;
$this->dupe_key = $dupe_key;
$this->involvedTypes = $involvedTypes;
}
}
7 changes: 6 additions & 1 deletion src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\InvolvedTypes;
use Psalm\Issue\FalsableReturnStatement;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidReturnStatement;
Expand Down Expand Up @@ -483,7 +484,11 @@ public static function analyze(
'The inferred type \'' . $inferred_type->getId()
. '\' does not match the declared return '
. 'type \'' . $local_return_type->getId() . '\' for ' . $cased_method_id,
new CodeLocation($source, $stmt->expr)
new CodeLocation($source, $stmt->expr),
new InvolvedTypes(
$inferred_type->getId(),
$local_return_type->getId()
)
),
$statements_analyzer->getSuppressedIssues()
);
Expand Down
25 changes: 25 additions & 0 deletions src/Psalm/InvolvedTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Psalm;

final class InvolvedTypes
{
private string $inferredType;
private string $declaredType;

public function __construct(string $inferredType, string $declaredType)
{
$this->inferredType = $inferredType;
$this->declaredType = $declaredType;
}

public function getInferredType(): string
{
return $this->inferredType;
}

public function getDeclaredType(): string
{
return $this->declaredType;
}
}
13 changes: 11 additions & 2 deletions src/Psalm/Issue/CodeIssue.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\InvolvedTypes;

use function array_pop;
use function explode;
Expand Down Expand Up @@ -32,12 +33,19 @@ abstract class CodeIssue
*/
public $dupe_key;

/**
* @var ?InvolvedTypes
*/
public $involvedTypes;

public function __construct(
string $message,
CodeLocation $code_location
CodeLocation $code_location,
?InvolvedTypes $involvedTypes = null
) {
$this->code_location = $code_location;
$this->message = $message;
$this->involvedTypes = $involvedTypes;
}

public function getShortLocationWithPrevious(): string
Expand Down Expand Up @@ -103,7 +111,8 @@ public function toIssueData(string $severity): IssueData
)
]
: null,
$this->dupe_key
$this->dupe_key,
$this->involvedTypes ?? null
);
}
}
4 changes: 4 additions & 0 deletions src/Psalm/Report.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ abstract class Report
/** @var int */
protected $total_expression_count;

/** @var bool */
protected $pretty_print_array = false;

/**
* @param array<int, IssueData> $issues_data
* @param array<string, int> $fixable_issue_counts
Expand All @@ -102,6 +105,7 @@ public function __construct(
$this->show_info = $report_options->show_info;
$this->pretty = $report_options->pretty;
$this->in_ci = $report_options->in_ci;
$this->pretty_print_array = $report_options->pretty_print_array;

$this->mixed_expression_count = $mixed_expression_count;
$this->total_expression_count = $total_expression_count;
Expand Down
32 changes: 32 additions & 0 deletions src/Psalm/Report/ConsoleReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
use Psalm\Internal\Analyzer\DataFlowNodeData;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use Psalm\Report\PrettyPrintArray\PrettyCompare;
use Psalm\Report\PrettyPrintArray\PrettyFormat;
use Psalm\Report\PrettyPrintArray\PrettyHelper;
use Throwable;

use function basename;
use function get_cfg_var;
Expand All @@ -14,6 +18,8 @@
use function strtr;
use function substr;

use const PHP_EOL;

final class ConsoleReport extends Report
{
/** @var string|null */
Expand Down Expand Up @@ -65,6 +71,10 @@ private function format(IssueData $issue_data): string
}
}

if ($this->pretty_print_array === true) {
$issue_string .= $this->prettyPrintArray($issue_data);
}

if ($issue_data->other_references) {
if ($this->show_snippet) {
$issue_string .= "\n";
Expand All @@ -76,6 +86,28 @@ private function format(IssueData $issue_data): string
return $issue_string;
}

private function prettyPrintArray(IssueData $issue_data): string
{
$prettyFormat = new PrettyFormat();
$prettyPaired = new PrettyCompare();

try {
$involvedTypes = $issue_data->involvedTypes;
if (!$involvedTypes) {
return '';
}

$arrayPrettyPrinted0 = $prettyFormat->format($involvedTypes->getDeclaredType());
$arrayPrettyPrinted1 = $prettyFormat->format($involvedTypes->getInferredType());
$toIssue = PHP_EOL.$prettyPaired->compare($arrayPrettyPrinted0, $arrayPrettyPrinted1);

return PrettyHelper::revertNormalizedTokens($toIssue);
} catch (Throwable $throwable) {
//todo: log ?
return 'Pretty Print Array failed for unexpected error. Error: ' . $throwable->getMessage();
}
}

/**
* @param non-empty-list<DataFlowNodeData|array{label: string, entry_path_type: string}> $taint_trace
*/
Expand Down
51 changes: 51 additions & 0 deletions src/Psalm/Report/PrettyPrintArray/PrettyCompare.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Psalm\Report\PrettyPrintArray;

use function count;
use function explode;
use function join;
use function sprintf;

use const PHP_EOL;

final class PrettyCompare
{
public function compare(string $inferred, string $declared): string
{
$formatTable = '| %-50s | %-50s ';

$requested = explode(PHP_EOL, $inferred);
$provided = explode(PHP_EOL, $declared);

$maxOf = count($requested) > count($provided) ? count($requested) : count($provided);
$indexOne = 0;
$paired = [];

for ($indexTwo = 0; $indexTwo <= $maxOf; $indexTwo++) {
$rowProvided = $provided[$indexTwo] ?? '';

if (isset($requested[$indexOne]) && $requested[$indexOne] !== '') {
$paired[] = [$requested[$indexOne], $rowProvided]; //tuple
} else {
$paired[] = ['', $rowProvided]; //tuple
}
$indexOne++;
}

if (!count($paired)) {
return '';
}

$pairedFormattedResult = [];
$pairedFormattedResult[] = '|';
$pairedFormattedResult[] = sprintf($formatTable, 'Expected', 'Provided');
$pairedFormattedResult[] = sprintf($formatTable, '---', '---');

foreach ($paired as $rows) {
$pairedFormattedResult[] = sprintf($formatTable, ...$rows);
}

return join(PHP_EOL, $pairedFormattedResult);
}
}
52 changes: 52 additions & 0 deletions src/Psalm/Report/PrettyPrintArray/PrettyCursorBracket.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Psalm\Report\PrettyPrintArray;

final class PrettyCursorBracket
{
private const BRACKET_OPEN = '{';
private const BRACKET_CLOSE = '}';

private int $nBrackets;
private string $char;
private bool $openedBracket = false;

public function __construct()
{
$this->nBrackets = 0;
$this->char = '';
}

public function accept(string $char): void
{
$this->char = $char;
if (self::BRACKET_OPEN === $this->char) {
$this->openedBracket = true;
$this->nBrackets++;
}

if (self::BRACKET_CLOSE === $char) {
if ($this->getNumberBrackets() === 0) {
$this->nBrackets = 1;
return;
}

$this->nBrackets--;
}
}

public function closed(): bool
{
if ($this->openedBracket === true && self::BRACKET_CLOSE === $this->char) {
if ($this->nBrackets <= 0) {
return true;
}
}
return false;
}

public function getNumberBrackets(): int
{
return $this->nBrackets;
}
}
Loading