Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 28 additions & 3 deletions src/Issue/Issue.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,44 @@

namespace Symfony\CodeBlockChecker\Issue;

use Doctrine\RST\Nodes\CodeNode;
use Symfony\CodeBlockChecker\Service\LineDetector;

/**
* Represent an error with some code.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Issue implements \Stringable
{
private CodeNode $node;
private string $text;
private string $type;
private string $file;
private int $line;

public function __construct(string $text, string $type, string $file, int $line)
/**
* The line in the file.
*/
private ?int $line;

/**
* The local line is inside the code node.
*/
private int $localLine;

public function __construct(CodeNode $node, string $text, string $type, string $file, int $localLine)
{
$this->node = $node;
$this->text = $text;
$this->type = $type;
$this->file = $file;
$this->line = $line;
$this->localLine = $localLine;
$this->line = null;
}

public function getHash(): string
{
return sha1($this->node->getValue());
}

public function getText(): string
Expand All @@ -39,6 +59,11 @@ public function getFile(): string

public function getLine(): int
{
if (null === $this->line) {
$offset = LineDetector::find($this->node);
$this->line = $offset + $this->localLine;
}

return $this->line;
}

Expand Down
10 changes: 5 additions & 5 deletions src/Listener/ValidCodeNodeListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private function validatePhp(CodeNode $node)
$text = str_replace($matches[0], '', $text);
$line = (int) $matches[1];
}
$this->errorManager->addIssue(new Issue($text, 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), $line));
$this->errorManager->addIssue(new Issue($node, $text, 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), $line));
}

private function validateXml(CodeNode $node)
Expand All @@ -101,7 +101,7 @@ private function validateXml(CodeNode $node)
return;
}

$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
}
}

Expand All @@ -116,7 +116,7 @@ private function validateYaml(CodeNode $node)
return;
}

$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
}
}

Expand All @@ -132,7 +132,7 @@ private function validateTwig(CodeNode $node)
// We cannot parse the TokenStream because we dont have all extensions loaded.
$this->twig->parse($tokens);
} catch (SyntaxError $e) {
$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
}
}

Expand All @@ -141,7 +141,7 @@ private function validateJson(CodeNode $node)
try {
$data = json_decode($node->getValue(), true, 512, JSON_THROW_ON_ERROR);
} catch (\JsonException $e) {
$this->errorManager->addIssue(new Issue($e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
$this->errorManager->addIssue(new Issue($node, $e->getMessage(), 'Invalid syntax', $node->getEnvironment()->getCurrentFileName(), 0));
}
}
}
41 changes: 41 additions & 0 deletions src/Service/LineDetector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Symfony\CodeBlockChecker\Service;

use Doctrine\RST\Nodes\CodeNode;

/**
* Find the line a CodeNode belongs to.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class LineDetector
{
/**
* Get the line number where the $node starts.
*/
public static function find(CodeNode $node): int
{
$environment = $node->getEnvironment();
if ('' === $environment->getCurrentFileName()) {
return 0;
}

$file = sprintf('%s/%s.rst', $environment->getCurrentDirectory(), $environment->getCurrentFileName());
$contents = explode(PHP_EOL, file_get_contents($file));
$codeBlock = explode(PHP_EOL, $node->getValue());

foreach ($contents as $i => $line) {
foreach ($codeBlock as $j => $needle) {
if (!str_contains($contents[$i + $j], $needle)) {
continue 2;
}
}

// The file's first row is 1 and our arrays first index is 0.
return $i + 1;
}

return 0;
}
}