Skip to content

Commit

Permalink
Process constructor parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 12, 2023
1 parent f2fcc1d commit 6fdeadf
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 12 deletions.
4 changes: 2 additions & 2 deletions identifier-extractor/src/ErrorFormatter.php
Expand Up @@ -40,8 +40,8 @@ public function formatErrors(AnalysisResult $analysisResult, Output $output): in
}

$output->writeRaw(Json::encode([
'repo' => $_SERVER['REPO'],
'branch' => $_SERVER['BRANCH'],
'repo' => $_SERVER['REPO'] ?? 'unknown',
'branch' => $_SERVER['BRANCH'] ?? 'unknown',
'data' => $json,
], true));

Expand Down
76 changes: 66 additions & 10 deletions identifier-extractor/src/Rule.php
Expand Up @@ -5,16 +5,24 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\CollectedDataNode;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\IdentifierRuleError;
use PHPStan\Rules\RuleErrorBuilder;
use function array_pop;
use function array_unique;
use function array_values;
use function in_array;

/**
* @implements \PHPStan\Rules\Rule<CollectedDataNode>
*/
class Rule implements \PHPStan\Rules\Rule
{

public function __construct(private ReflectionProvider $reflectionProvider)
{
}

public function getNodeType(): string
{
return CollectedDataNode::class;
Expand All @@ -37,27 +45,75 @@ public function processNode(Node $node, Scope $scope): array
$injected[$key] = array_values(array_unique($values));
}

var_dump($injected);

foreach ($node->get(RuleErrorBuilderCollector::class) as $rows) {
foreach ($rows as $row) {
$errors[] = RuleErrorBuilder::message('Metadata')
->identifier('phpstanIdentifierExtractor.data')
->metadata($row)
->build();
foreach ($this->processRows($rows, $injected) as $error) {
$errors[] = $error;
}
}

foreach ($node->get(ErrorWithIdentifierCollector::class) as $rows) {
foreach ($rows as $row) {
foreach ($this->processRows($rows, $injected) as $error) {
$errors[] = $error;
}
}

return $errors;
}

/**
* @param list<array{identifiers: non-empty-list<string>, class: string, file: string, line: int}> $rows
* @param array<string, list<string>> $injected
* @return list<IdentifierRuleError>
*/
private function processRows(array $rows, array $injected): array
{
$errors = [];
foreach ($rows as $row) {
foreach ($this->findOrigins($row['class'], $injected) as $origin) {
$errors[] = RuleErrorBuilder::message('Metadata')
->identifier('phpstanIdentifierExtractor.data')
->metadata($row)
->build();
->metadata([
'identifiers' => $row['identifiers'],
'class' => $origin,
'file' => $row['file'],
'line' => $row['line'],
])->build();
}
}

return $errors;
}

/**
* @param array<string, list<string>> $injected
* @return list<string>
*/
private function findOrigins(string $class, array $injected): array
{
$origins = [];
$stack = [$class];
while (count($stack) > 0) {
$item = array_pop($stack);
if ($this->reflectionProvider->hasClass($item)) {
$reflection = $this->reflectionProvider->getClass($item);
if ($reflection->implementsInterface(\PHPStan\Rules\Rule::class)) {
$origins[] = $item;
}
}

if (!isset($injected[$item])) {
continue;
}

foreach ($injected[$item] as $v) {
if (in_array($v, $stack, true)) {
continue;
}
$stack[] = $v;
}
}

return $origins;
}

}

0 comments on commit 6fdeadf

Please sign in to comment.